示例#1
0
 /** 
  * Gets the HTML of the diff that MediaWiki displays to the user.
  */
 public function getHtmlDiff($pageTitle, $oldText, $newText)
 {
     $de = new DifferenceEngine($pageTitle);
     $de->setText($oldText, $newText);
     $difftext = $de->getDiff("Old", "New");
     return $difftext;
 }
    /**
     * Replace entire showEditForm, need to add our own textbox and stuff
     */
    function showEditForm($formCallback = null)
    {
        global $wgOut, $wgUser, $wgLang, $wgContLang, $wgMaxArticleSize, $wgTitle, $wgRequest;
        # If $wgTitle is null, that means we're in API mode.
        # Some hook probably called this function  without checking
        # for is_null($wgTitle) first. Bail out right here so we don't
        # do lots of work just to discard it right after.
        if (is_null($wgTitle)) {
            return;
        }
        $fname = 'EditPage::showEditForm';
        wfProfileIn($fname);
        $sk = $wgUser->getSkin();
        wfRunHooks('EditPage::showEditForm:initial', array(&$this));
        #need to parse the preview early so that we know which templates are used,
        #otherwise users with "show preview after edit box" will get a blank list
        #we parse this near the beginning so that setHeaders can do the title
        #setting work instead of leaving it in getPreviewText
        $previewOutput = '';
        if ($this->formtype == 'preview') {
            $previewOutput = $this->getPreviewText();
        }
        $this->setHeaders();
        # Enabled article-related sidebar, toplinks, etc.
        $wgOut->setArticleRelated(true);
        if ($this->isConflict) {
            $wgOut->wrapWikiMsg("<div class='mw-explainconflict'>\n\$1</div>", 'explainconflict');
            $this->textbox2 = $this->textbox1;
            $this->textbox1 = $this->getContent();
            $this->edittime = $this->mArticle->getTimestamp();
            # MeanEditor: too complicated for visual editing
            $this->noVisualEditor = false;
        } else {
            if ($this->section != '' && $this->section != 'new') {
                $matches = array();
                if (!$this->summary && !$this->preview && !$this->diff) {
                    preg_match("/^(=+)(.+)\\1/mi", $this->textbox1, $matches);
                    if (!empty($matches[2])) {
                        global $wgParser;
                        $this->summary = "/* " . $wgParser->stripSectionName(trim($matches[2])) . " */ ";
                    }
                }
            }
            if ($this->missingComment) {
                $wgOut->wrapWikiMsg('<div id="mw-missingcommenttext">$1</div>', 'missingcommenttext');
            }
            if ($this->missingSummary && $this->section != 'new') {
                $wgOut->wrapWikiMsg('<div id="mw-missingsummary">$1</div>', 'missingsummary');
            }
            if ($this->missingSummary && $this->section == 'new') {
                $wgOut->wrapWikiMsg('<div id="mw-missingcommentheader">$1</div>', 'missingcommentheader');
            }
            if ($this->hookError !== '') {
                $wgOut->addWikiText($this->hookError);
            }
            if (!$this->checkUnicodeCompliantBrowser()) {
                $wgOut->addWikiMsg('nonunicodebrowser');
            }
            if (isset($this->mArticle) && isset($this->mArticle->mRevision)) {
                // Let sysop know that this will make private content public if saved
                if (!$this->mArticle->mRevision->userCan(Revision::DELETED_TEXT)) {
                    $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-permission');
                } else {
                    if ($this->mArticle->mRevision->isDeleted(Revision::DELETED_TEXT)) {
                        $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-view');
                    }
                }
                if (!$this->mArticle->mRevision->isCurrent()) {
                    $this->mArticle->setOldSubtitle($this->mArticle->mRevision->getId());
                    $wgOut->addWikiMsg('editingold');
                }
            }
        }
        if (wfReadOnly()) {
            $wgOut->wrapWikiMsg("<div id=\"mw-read-only-warning\">\n\$1\n</div>", array('readonlywarning', wfReadOnlyReason()));
            # MeanEditor: visual editing makes no sense here
            $this->noVisualEditor = true;
        } elseif ($wgUser->isAnon() && $this->formtype != 'preview') {
            $wgOut->wrapWikiMsg('<div id="mw-anon-edit-warning">$1</div>', 'anoneditwarning');
        } else {
            if ($this->isCssJsSubpage) {
                # Check the skin exists
                if ($this->isValidCssJsSubpage) {
                    if ($this->formtype !== 'preview') {
                        $wgOut->addWikiMsg('usercssjsyoucanpreview');
                    }
                } else {
                    $wgOut->addWikiMsg('userinvalidcssjstitle', $wgTitle->getSkinFromCssJsSubpage());
                }
            }
        }
        $classes = array();
        // Textarea CSS
        if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) {
        } elseif ($this->mTitle->isProtected('edit')) {
            # Is the title semi-protected?
            if ($this->mTitle->isSemiProtected()) {
                $noticeMsg = 'semiprotectedpagewarning';
                $classes[] = 'mw-textarea-sprotected';
            } else {
                # Then it must be protected based on static groups (regular)
                $noticeMsg = 'protectedpagewarning';
                $classes[] = 'mw-textarea-protected';
            }
            $wgOut->addHTML("<div class='mw-warning-with-logexcerpt'>\n");
            $wgOut->addWikiMsg($noticeMsg);
            LogEventsList::showLogExtract($wgOut, 'protect', $this->mTitle->getPrefixedText(), '', 1);
            $wgOut->addHTML("</div>\n");
        }
        if ($this->mTitle->isCascadeProtected()) {
            # Is this page under cascading protection from some source pages?
            list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources();
            $notice = "<div class='mw-cascadeprotectedwarning'>\$1\n";
            $cascadeSourcesCount = count($cascadeSources);
            if ($cascadeSourcesCount > 0) {
                # Explain, and list the titles responsible
                foreach ($cascadeSources as $page) {
                    $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
                }
            }
            $notice .= '</div>';
            $wgOut->wrapWikiMsg($notice, array('cascadeprotectedwarning', $cascadeSourcesCount));
        }
        if (!$this->mTitle->exists() && $this->mTitle->getRestrictions('create')) {
            $wgOut->wrapWikiMsg('<div class="mw-titleprotectedwarning">$1</div>', 'titleprotectedwarning');
        }
        if ($this->kblength === false) {
            # MeanEditor: the length will probably be different in HTML
            $this->kblength = (int) (strlen($this->textbox1) / 1024);
        }
        if ($this->tooBig || $this->kblength > $wgMaxArticleSize) {
            $wgOut->addHTML("<div class='error' id='mw-edit-longpageerror'>\n");
            $wgOut->addWikiMsg('longpageerror', $wgLang->formatNum($this->kblength), $wgLang->formatNum($wgMaxArticleSize));
            $wgOut->addHTML("</div>\n");
        } elseif ($this->kblength > 29) {
            $wgOut->addHTML("<div id='mw-edit-longpagewarning'>\n");
            $wgOut->addWikiMsg('longpagewarning', $wgLang->formatNum($this->kblength));
            $wgOut->addHTML("</div>\n");
        }
        $q = 'action=' . $this->action;
        #if ( "no" == $redirect ) { $q .= "&redirect=no"; }
        $action = $wgTitle->escapeLocalURL($q);
        $summary = wfMsg('summary');
        $subject = wfMsg('subject');
        $cancel = $sk->makeKnownLink($wgTitle->getPrefixedText(), wfMsgExt('cancel', array('parseinline')));
        $separator = wfMsgExt('pipe-separator', 'escapenoentities');
        $edithelpurl = Skin::makeInternalOrExternalUrl(wfMsgForContent('edithelppage'));
        $edithelp = '<a target="helpwindow" href="' . $edithelpurl . '">' . htmlspecialchars(wfMsg('edithelp')) . '</a> ' . htmlspecialchars(wfMsg('newwindow'));
        global $wgRightsText;
        if ($wgRightsText) {
            $copywarnMsg = array('copyrightwarning', '[[' . wfMsgForContent('copyrightpage') . ']]', $wgRightsText);
        } else {
            $copywarnMsg = array('copyrightwarning2', '[[' . wfMsgForContent('copyrightpage') . ']]');
        }
        /* MeanEditor: always disable the toolbar */
        if ($wgUser->getOption('showtoolbar') and !$this->isCssJsSubpage) {
            # prepare toolbar for edit buttons
            $toolbar = '';
        } else {
            $toolbar = '';
        }
        // activate checkboxes if user wants them to be always active
        if (!$this->preview && !$this->diff) {
            # Sort out the "watch" checkbox
            if ($wgUser->getOption('watchdefault')) {
                # Watch all edits
                $this->watchthis = true;
            } elseif ($wgUser->getOption('watchcreations') && !$this->mTitle->exists()) {
                # Watch creations
                $this->watchthis = true;
            } elseif ($this->mTitle->userIsWatching()) {
                # Already watched
                $this->watchthis = true;
            }
            # May be overriden by request parameters
            if ($wgRequest->getBool('watchthis')) {
                $this->watchthis = true;
            }
            if ($wgUser->getOption('minordefault')) {
                $this->minoredit = true;
            }
            # MeanEditor: User preference
            if ($wgUser->getOption('prefer_traditional_editor')) {
                $this->userWantsTraditionalEditor = true;
            }
        }
        $wgOut->addHTML($this->editFormPageTop);
        if ($wgUser->getOption('previewontop')) {
            $this->displayPreviewArea($previewOutput, true);
        }
        $wgOut->addHTML($this->editFormTextTop);
        # if this is a comment, show a subject line at the top, which is also the edit summary.
        # Otherwise, show a summary field at the bottom
        $summarytext = $wgContLang->recodeForEdit($this->summary);
        # If a blank edit summary was previously provided, and the appropriate
        # user preference is active, pass a hidden tag as wpIgnoreBlankSummary. This will stop the
        # user being bounced back more than once in the event that a summary
        # is not required.
        #####
        # For a bit more sophisticated detection of blank summaries, hash the
        # automatic one and pass that in the hidden field wpAutoSummary.
        $summaryhiddens = '';
        if ($this->missingSummary) {
            $summaryhiddens .= Xml::hidden('wpIgnoreBlankSummary', true);
        }
        $autosumm = $this->autoSumm ? $this->autoSumm : md5($this->summary);
        $summaryhiddens .= Xml::hidden('wpAutoSummary', $autosumm);
        if ($this->section == 'new') {
            $commentsubject = '';
            if (!$wgRequest->getBool('nosummary')) {
                # Add a class if 'missingsummary' is triggered to allow styling of the summary line
                $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
                $commentsubject = Xml::tags('label', array('for' => 'wpSummary'), $subject);
                $commentsubject = Xml::tags('span', array('class' => $summaryClass, 'id' => "wpSummaryLabel"), $commentsubject);
                $commentsubject .= '&nbsp;';
                $commentsubject .= Xml::input('wpSummary', 60, $summarytext, array('id' => 'wpSummary', 'maxlength' => '200', 'tabindex' => '1'));
            }
            $editsummary = "<div class='editOptions'>\n";
            global $wgParser;
            $formattedSummary = wfMsgForContent('newsectionsummary', $wgParser->stripSectionName($this->summary));
            $subjectpreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">" . wfMsg('subject-preview') . $sk->commentBlock($formattedSummary, $this->mTitle, true) . "</div>\n" : '';
            $summarypreview = '';
        } else {
            $commentsubject = '';
            # Add a class if 'missingsummary' is triggered to allow styling of the summary line
            $summaryClass = $this->missingSummary ? 'mw-summarymissed' : 'mw-summary';
            $editsummary = Xml::tags('label', array('for' => 'wpSummary'), $summary);
            $editsummary = Xml::tags('span', array('class' => $summaryClass, 'id' => "wpSummaryLabel"), $editsummary) . ' ';
            $editsummary .= Xml::input('wpSummary', 60, $summarytext, array('id' => 'wpSummary', 'maxlength' => '200', 'tabindex' => '1'));
            // No idea where this is closed.
            $editsummary = Xml::openElement('div', array('class' => 'editOptions')) . $editsummary . '<br/>';
            $summarypreview = '';
            if ($summarytext && $this->preview) {
                $summarypreview = Xml::tags('div', array('class' => 'mw-summary-preview'), wfMsg('summary-preview') . $sk->commentBlock($this->summary, $this->mTitle));
            }
            $subjectpreview = '';
        }
        $commentsubject .= $summaryhiddens;
        # Set focus to the edit box on load, except on preview or diff, where it would interfere with the display
        if (!$this->preview && !$this->diff) {
            $wgOut->setOnloadHandler('document.editform.wpTextbox1.focus()');
        }
        $templates = $this->getTemplates();
        $formattedtemplates = $sk->formatTemplates($templates, $this->preview, $this->section != '');
        $hiddencats = $this->mArticle->getHiddenCategories();
        $formattedhiddencats = $sk->formatHiddenCategories($hiddencats);
        global $wgUseMetadataEdit;
        if ($wgUseMetadataEdit) {
            $metadata = $this->mMetaData;
            $metadata = htmlspecialchars($wgContLang->recodeForEdit($metadata));
            $top = wfMsgWikiHtml('metadata_help');
            /* ToDo: Replace with clean code */
            $ew = $wgUser->getOption('editwidth');
            if ($ew) {
                $ew = " style=\"width:100%\"";
            } else {
                $ew = '';
            }
            $cols = $wgUser->getIntOption('cols');
            /* /ToDo */
            $metadata = $top . "<textarea name='metadata' rows='3' cols='{$cols}'{$ew}>{$metadata}</textarea>";
        } else {
            $metadata = "";
        }
        $recreate = '';
        if ($this->wasDeletedSinceLastEdit()) {
            if ('save' != $this->formtype) {
                $wgOut->wrapWikiMsg("<div class='error mw-deleted-while-editing'>\n\$1</div>", 'deletedwhileediting');
            } else {
                // Hide the toolbar and edit area, user can click preview to get it back
                // Add an confirmation checkbox and explanation.
                $toolbar = '';
                $recreate = '<div class="mw-confirm-recreate">' . $wgOut->parse(wfMsg('confirmrecreate', $this->lastDelete->user_name, $this->lastDelete->log_comment)) . Xml::checkLabel(wfMsg('recreate'), 'wpRecreate', 'wpRecreate', false, array('title' => $sk->titleAttrib('recreate'), 'tabindex' => 1, 'id' => 'wpRecreate')) . '</div>';
            }
        }
        $tabindex = 2;
        $checkboxes = $this->getCheckboxes($tabindex, $sk, array('minor' => $this->minoredit, 'watch' => $this->watchthis, 'want_traditional_editor' => $this->userWantsTraditionalEditor));
        $checkboxhtml = implode($checkboxes, "\n");
        $buttons = $this->getEditButtons($tabindex);
        $buttonshtml = implode($buttons, "\n");
        $safemodehtml = $this->checkUnicodeCompliantBrowser() ? '' : Xml::hidden('safemode', '1');
        $wgOut->addHTML(<<<END
{$toolbar}
<form id="editform" name="editform" method="post" action="{$action}" enctype="multipart/form-data">
END
);
        if (is_callable($formCallback)) {
            call_user_func_array($formCallback, array(&$wgOut));
        }
        wfRunHooks('EditPage::showEditForm:fields', array(&$this, &$wgOut));
        // Put these up at the top to ensure they aren't lost on early form submission
        $this->showFormBeforeText();
        $wgOut->addHTML(<<<END
{$recreate}
{$commentsubject}
{$subjectpreview}
{$this->editFormTextBeforeContent}
END
);
        if ($this->isConflict || $this->diff) {
            # MeanEditor: should be redundant, but let's be sure
            $this->noVisualEditor = true;
        }
        # MeanEditor: also apply htmlspecialchars? See $encodedtext
        $html_text = $this->safeUnicodeOutput($this->textbox1);
        if (!($this->noVisualEditor || $this->userWantsTraditionalEditor)) {
            $this->noVisualEditor = wfRunHooks('EditPage::wiki2html', array($this->mArticle, $wgUser, &$this, &$html_text));
        }
        if (!$this->noVisualEditor && !$this->userWantsTraditionalEditor) {
            $this->noVisualEditor = wfRunHooks('EditPage::showBox', array(&$this, $html_text, $rows, $cols, $ew));
        }
        if (!$this->noVisualEditor && !$this->userWantsTraditionalEditor) {
            $wgOut->addHTML("<input type='hidden' value=\"0\" name=\"wpNoVisualEditor\" />\n");
        } else {
            $wgOut->addHTML("<input type='hidden' value=\"1\" name=\"wpNoVisualEditor\" />\n");
            $this->showTextbox1($classes);
        }
        $wgOut->wrapWikiMsg("<div id=\"editpage-copywarn\">\n\$1\n</div>", $copywarnMsg);
        $wgOut->addHTML(<<<END
{$this->editFormTextAfterWarn}
{$metadata}
{$editsummary}
{$summarypreview}
{$checkboxhtml}
{$safemodehtml}
END
);
        $wgOut->addHTML("<div class='editButtons'>\n{$buttonshtml}\n\t<span class='editHelp'>{$cancel}{$separator}{$edithelp}</span>\n</div><!-- editButtons -->\n</div><!-- editOptions -->");
        /**
         * To make it harder for someone to slip a user a page
         * which submits an edit form to the wiki without their
         * knowledge, a random token is associated with the login
         * session. If it's not passed back with the submission,
         * we won't save the page, or render user JavaScript and
         * CSS previews.
         *
         * For anon editors, who may not have a session, we just
         * include the constant suffix to prevent editing from
         * broken text-mangling proxies.
         */
        $token = htmlspecialchars($wgUser->editToken());
        $wgOut->addHTML("\n<input type='hidden' value=\"{$token}\" name=\"wpEditToken\" />\n");
        $this->showEditTools();
        $wgOut->addHTML(<<<END
{$this->editFormTextAfterTools}
<div class='templatesUsed'>
{$formattedtemplates}
</div>
<div class='hiddencats'>
{$formattedhiddencats}
</div>
END
);
        if ($this->isConflict && wfRunHooks('EditPageBeforeConflictDiff', array(&$this, &$wgOut))) {
            $wgOut->wrapWikiMsg('==$1==', "yourdiff");
            $de = new DifferenceEngine($this->mTitle);
            $de->setText($this->textbox2, $this->textbox1);
            $de->showDiff(wfMsg("yourtext"), wfMsg("storedversion"));
            $wgOut->wrapWikiMsg('==$1==', "yourtext");
            $this->showTextbox2();
        }
        $wgOut->addHTML($this->editFormTextBottom);
        $wgOut->addHTML("</form>\n");
        if (!$wgUser->getOption('previewontop')) {
            $this->displayPreviewArea($previewOutput, false);
        }
        wfProfileOut($fname);
    }
 function makeADifference($text, $title, $section)
 {
     global $wgOut;
     /* make an article object */
     $rtitle = Title::newFromText($title);
     $rarticle = new Article($rtitle, $rtitle->getArticleID());
     $epage = new EditPage($rarticle);
     $epage->section = $section;
     /* customized getDiff from EditPage */
     $oldtext = $epage->mArticle->fetchContent();
     $edittime = $epage->mArticle->getTimestamp();
     $newtext = $epage->mArticle->replaceSection($section, $text, '', $edittime);
     $newtext = $epage->mArticle->preSaveTransform($newtext);
     $oldtitle = wfMsgExt('currentrev', array('parseinline'));
     $newtitle = wfMsgExt('yourtext', array('parseinline'));
     if ($oldtext !== false || $newtext != '') {
         $de = new DifferenceEngine($epage->mTitle);
         $de->setText($oldtext, $newtext);
         $difftext = $de->getDiff($oldtitle, $newtitle);
     } else {
         $difftext = '';
     }
     $diffdiv = '<div id="wikiDiff">' . $difftext . '</div>';
     $wgOut->addHTML($diffdiv);
 }
 function perform($bPerformEdits = true)
 {
     global $wgRequest, $wgOut, $wgUser, $wgTitle, $wgLang;
     $iMaxPerCriterion = $bPerformEdits ? MER_MAX_EXECUTE_PAGES : MER_MAX_PREVIEW_DIFFS;
     $aErrors = array();
     $aPages = $this->getPages($aErrors, $iMaxPerCriterion);
     if ($aPages === null) {
         $this->showForm(wfMsg('masseditregex-err-nopages'));
         return;
     }
     // Show the form again ready for further editing if we're just previewing
     if (!$bPerformEdits) {
         $this->showForm();
     }
     $diff = new DifferenceEngine();
     $diff->showDiffStyle();
     // send CSS link to the browser for diff colours
     $wgOut->addHTML('<ul>');
     if (count($aErrors)) {
         $wgOut->addHTML('<li>' . join('</li><li> ', $aErrors) . '</li>');
     }
     $htmlDiff = '';
     $editToken = $wgUser->editToken();
     $iArticleCount = 0;
     foreach ($aPages as $p) {
         $iArticleCount++;
         if (!isset($p['revisions'])) {
             $wgOut->addHTML('<li>' . wfMsg('masseditregex-page-not-exists', $p['title']) . '</li>');
             continue;
             // empty page
         }
         $curContent = $p['revisions'][0]['*'];
         $iCount = 0;
         $newContent = $curContent;
         foreach ($this->aMatch as $i => $strMatch) {
             $this->strNextReplace = $this->aReplace[$i];
             $result = @preg_replace_callback($strMatch, array($this, 'regexCallback'), $newContent, -1, $iCount);
             if ($result !== null) {
                 $newContent = $result;
             } else {
                 $strErrorMsg = '<li>' . wfMsg('masseditregex-badregex') . ' <b>' . htmlspecialchars($strMatch) . '</b></li>';
                 $wgOut->addHTML($strErrorMsg);
                 unset($this->aMatch[$i]);
             }
         }
         if ($bPerformEdits) {
             // Not in preview mode, make the edits
             $wgOut->addHTML('<li>' . wfMsg('masseditregex-num-changes', $p['title'], $iCount) . '</li>');
             $req = new DerivativeRequest($wgRequest, array('action' => 'edit', 'bot' => true, 'title' => $p['title'], 'summary' => $this->strSummary, 'text' => $newContent, 'basetimestamp' => $p['starttimestamp'], 'watchlist' => 'nochange', 'nocreate' => 1, 'token' => $editToken), true);
             $processor = new ApiMain($req, true);
             try {
                 $processor->execute();
             } catch (UsageException $e) {
                 $wgOut->addHTML('<li><ul><li>' . wfMsg('masseditregex-editfailed') . ' ' . $e . '</li></ul></li>');
             }
         } else {
             // In preview mode, display the first few diffs
             $diff->setText($curContent, $newContent);
             $htmlDiff .= $diff->getDiff('<b>' . $p['title'] . ' - ' . wfMsg('masseditregex-before') . '</b>', '<b>' . wfMsg('masseditregex-after') . '</b>');
             if ($iArticleCount >= MER_MAX_PREVIEW_DIFFS) {
                 $htmlDiff .= Xml::element('p', null, wfMsg('masseditregex-max-preview-diffs', $wgLang->formatNum(MER_MAX_PREVIEW_DIFFS)));
                 break;
             }
         }
     }
     $wgOut->addHTML('</ul>');
     if ($bPerformEdits) {
         $wgOut->addWikiMsg('masseditregex-num-articles-changed', $iArticleCount);
         $wgOut->addHTML($this->sk->makeKnownLinkObj(SpecialPage::getSafeTitleFor('Contributions', $wgUser->getName()), wfMsgHtml('masseditregex-view-full-summary')));
     } else {
         // Only previewing, show the diffs now (after any errors)
         $wgOut->addHTML($htmlDiff);
     }
 }
示例#5
0
 private function extractRowInfo($row)
 {
     $revision = new Revision($row);
     $title = $revision->getTitle();
     $vals = array();
     if ($this->fld_ids) {
         $vals['revid'] = intval($revision->getId());
         // $vals['oldid'] = intval( $row->rev_text_id ); // todo: should this be exposed?
         if (!is_null($revision->getParentId())) {
             $vals['parentid'] = intval($revision->getParentId());
         }
     }
     if ($this->fld_flags && $revision->isMinor()) {
         $vals['minor'] = '';
     }
     if ($this->fld_user || $this->fld_userid) {
         if ($revision->isDeleted(Revision::DELETED_USER)) {
             $vals['userhidden'] = '';
         } else {
             if ($this->fld_user) {
                 $vals['user'] = $revision->getUserText();
             }
             $userid = $revision->getUser();
             if (!$userid) {
                 $vals['anon'] = '';
             }
             if ($this->fld_userid) {
                 $vals['userid'] = $userid;
             }
         }
     }
     if ($this->fld_timestamp) {
         $vals['timestamp'] = wfTimestamp(TS_ISO_8601, $revision->getTimestamp());
     }
     if ($this->fld_size) {
         if (!is_null($revision->getSize())) {
             $vals['size'] = intval($revision->getSize());
         } else {
             $vals['size'] = 0;
         }
     }
     if ($this->fld_sha1) {
         if ($revision->getSha1() != '') {
             $vals['sha1'] = wfBaseConvert($revision->getSha1(), 36, 16, 40);
         } else {
             $vals['sha1'] = '';
         }
     }
     if ($this->fld_comment || $this->fld_parsedcomment) {
         if ($revision->isDeleted(Revision::DELETED_COMMENT)) {
             $vals['commenthidden'] = '';
         } else {
             $comment = $revision->getComment();
             if ($this->fld_comment) {
                 $vals['comment'] = $comment;
             }
             if ($this->fld_parsedcomment) {
                 $vals['parsedcomment'] = Linker::formatComment($comment, $title);
             }
         }
     }
     if ($this->fld_tags) {
         if ($row->ts_tags) {
             $tags = explode(',', $row->ts_tags);
             $this->getResult()->setIndexedTagName($tags, 'tag');
             $vals['tags'] = $tags;
         } else {
             $vals['tags'] = array();
         }
     }
     if (!is_null($this->token)) {
         $tokenFunctions = $this->getTokenFunctions();
         foreach ($this->token as $t) {
             $val = call_user_func($tokenFunctions[$t], $title->getArticleID(), $title, $revision);
             if ($val === false) {
                 $this->setWarning("Action '{$t}' is not allowed for the current user");
             } else {
                 $vals[$t . 'token'] = $val;
             }
         }
     }
     $text = null;
     global $wgParser;
     if ($this->fld_content || !is_null($this->difftotext)) {
         $text = $revision->getText();
         // Expand templates after getting section content because
         // template-added sections don't count and Parser::preprocess()
         // will have less input
         if ($this->section !== false) {
             $text = $wgParser->getSection($text, $this->section, false);
             if ($text === false) {
                 $this->dieUsage("There is no section {$this->section} in r" . $revision->getId(), 'nosuchsection');
             }
         }
     }
     if ($this->fld_content && !$revision->isDeleted(Revision::DELETED_TEXT)) {
         if ($this->generateXML) {
             $wgParser->startExternalParse($title, ParserOptions::newFromContext($this->getContext()), OT_PREPROCESS);
             $dom = $wgParser->preprocessToDom($text);
             if (is_callable(array($dom, 'saveXML'))) {
                 $xml = $dom->saveXML();
             } else {
                 $xml = $dom->__toString();
             }
             $vals['parsetree'] = $xml;
         }
         if ($this->expandTemplates && !$this->parseContent) {
             $text = $wgParser->preprocess($text, $title, ParserOptions::newFromContext($this->getContext()));
         }
         if ($this->parseContent) {
             $text = $wgParser->parse($text, $title, ParserOptions::newFromContext($this->getContext()))->getText();
         }
         ApiResult::setContent($vals, $text);
     } elseif ($this->fld_content) {
         $vals['texthidden'] = '';
     }
     if (!is_null($this->diffto) || !is_null($this->difftotext)) {
         global $wgAPIMaxUncachedDiffs;
         static $n = 0;
         // Number of uncached diffs we've had
         if ($n < $wgAPIMaxUncachedDiffs) {
             $vals['diff'] = array();
             $context = new DerivativeContext($this->getContext());
             $context->setTitle($title);
             if (!is_null($this->difftotext)) {
                 $engine = new DifferenceEngine($context);
                 $engine->setText($text, $this->difftotext);
             } else {
                 $engine = new DifferenceEngine($context, $revision->getID(), $this->diffto);
                 $vals['diff']['from'] = $engine->getOldid();
                 $vals['diff']['to'] = $engine->getNewid();
             }
             $difftext = $engine->getDiffBody();
             ApiResult::setContent($vals['diff'], $difftext);
             if (!$engine->wasCacheHit()) {
                 $n++;
             }
         } else {
             $vals['diff']['notcached'] = '';
         }
     }
     return $vals;
 }
	public function execute( $messages ) {
		global $wgOut, $wgLang;

		$this->out = $wgOut;

		// Set up diff engine
		$diff = new DifferenceEngine;
		$diff->showDiffStyle();
		$diff->setReducedLineNumbers();

		// Check whether we do processing
		$process = $this->allowProcess();

		// Initialise collection
		$group = $this->getGroup();
		$code = $this->getCode();
		$collection = $group->initCollection( $code );
		$collection->loadTranslations();

		$this->out->addHTML( $this->doHeader() );

		// Determine changes
		$alldone = $process;
		$changed = array();

		foreach ( $messages as $key => $value ) {
			$fuzzy = $old = false;

			if ( isset( $collection[$key] ) ) {
				$old = $collection[$key]->translation();
			}

			// No changes at all, ignore
			if ( strval( $old ) === strval( $value ) ) {
				continue;
			}

			if ( $old === false ) {
				$name = wfMsgHtml( 'translate-manage-import-new',
					'<code style="font-weight:normal;">' . htmlspecialchars( $key ) . '</code>'
				);
				$text = TranslateUtils::convertWhiteSpaceToHTML( $value );
				$changed[] = self::makeSectionElement( $name, 'new', $text );
			} else {
				$diff->setText( $old, $value );
				$text = $diff->getDiff( '', '' );
				$type = 'changed';

				global $wgRequest;
				$action = $wgRequest->getVal( self::escapeNameForPHP( "action-$type-$key" ) );

				if ( $process ) {
					if ( !count( $changed ) ) {
						$changed[] = '<ul>';
					}

					if ( $action === null ) {
						$message = wfMsgExt( 'translate-manage-inconsistent', 'parseinline', wfEscapeWikiText( "action-$type-$key" ) );
						$changed[] = "<li>$message</li></ul>";
						$process = false;
					} else {
						// Check processing time
						if ( !isset( $this->time ) ) {
							$this->time = wfTimestamp();
						}

						$message = self::doAction(
							$action,
							$group,
							$key,
							$code,
							$value
						);

						$key = array_shift( $message );
						$params = $message;
						$message = wfMsgExt( $key, 'parseinline', $params );
						$changed[] = "<li>$message</li>";

						if ( $this->checkProcessTime() ) {
							$process = false;
							$duration = $wgLang->formatNum( $this->processingTime );
							$message = wfMsgExt( 'translate-manage-toolong', 'parseinline', $duration );
							$changed[] = "<li>$message</li></ul>";
						}
						continue;
					}
				}

				$alldone = false;

				$actions = $this->getActions();
				$defaction = $this->getDefaultAction( $fuzzy, $action );

				$act = array();

				foreach ( $actions as $action ) {
					$label = wfMsg( "translate-manage-action-$action" );
					$name = self::escapeNameForPHP( "action-$type-$key" );
					$id = Sanitizer::escapeId( "action-$key-$action" );
					$act[] = Xml::radioLabel( $label, $name, $action, $id, $action === $defaction );
				}

				$name = wfMsg( 'translate-manage-import-diff',
					'<code style="font-weight:normal;">' . htmlspecialchars( $key ) . '</code>',
					implode( ' ', $act )
				);

				$changed[] = self::makeSectionElement( $name, $type, $text );
			}
		}

		if ( !$process ) {
			$collection->filter( 'hastranslation', false );
			$keys = $collection->getMessageKeys();

			$diff = array_diff( $keys, array_keys( $messages ) );

			foreach ( $diff as $s ) {
				// @todo FIXME: Use CSS file.
				$name = wfMsgHtml( 'translate-manage-import-deleted',
					'<code style="font-weight:normal;">' . htmlspecialchars( $s ) . '</code>'
				);
				$text = TranslateUtils::convertWhiteSpaceToHTML(  $collection[$s]->translation() );
				$changed[] = self::makeSectionElement( $name, 'deleted', $text );
			}
		}

		if ( $process || ( !count( $changed ) && $code !== 'en' ) ) {
			if ( !count( $changed ) ) {
				$this->out->addWikiMsg( 'translate-manage-nochanges-other' );
			}

			if ( !count( $changed ) || strpos( $changed[count( $changed ) - 1], '<li>' ) !== 0 ) {
				$changed[] = '<ul>';
			}

			$message = wfMsgExt( 'translate-manage-import-done', 'parseinline' );
			$changed[] = "<li>$message</li></ul>";
			$this->out->addHTML( implode( "\n", $changed ) );
		} else {
			// END
			if ( count( $changed ) ) {
				if ( $code === 'en' ) {
					$this->out->addWikiMsg( 'translate-manage-intro-en' );
				} else {
					$lang = TranslateUtils::getLanguageName( $code, false, $wgLang->getCode() );
					$this->out->addWikiMsg( 'translate-manage-intro-other', $lang );
				}
				$this->out->addHTML( Html::hidden( 'language', $code ) );
				$this->out->addHTML( implode( "\n", $changed ) );
				$this->out->addHTML( Xml::submitButton( wfMsg( 'translate-manage-submit' ) ) );
			} else {
				$this->out->addWikiMsg( 'translate-manage-nochanges' );
			}
		}

		$this->out->addHTML( $this->doFooter() );
		return $alldone;
	}
示例#7
0
 /**
  * Show "your edit contains spam" page with your diff and text
  *
  * @param $match Text which triggered one or more filters
  */
 public function spamPageWithContent($match = false)
 {
     global $wgOut;
     $this->textbox2 = $this->textbox1;
     $wgOut->prepareErrorPage(wfMessage('spamprotectiontitle'));
     $wgOut->addHTML('<div id="spamprotected">');
     $wgOut->addWikiMsg('spamprotectiontext');
     if ($match) {
         $wgOut->addWikiMsg('spamprotectionmatch', wfEscapeWikiText($match));
     }
     $wgOut->addHTML('</div>');
     $wgOut->wrapWikiMsg('<h2>$1</h2>', "yourdiff");
     $de = new DifferenceEngine($this->mArticle->getContext());
     $de->setText($this->getCurrentText(), $this->textbox2);
     $de->showDiff(wfMsg("storedversion"), wfMsgExt('yourtext', 'parseinline'));
     $wgOut->wrapWikiMsg('<h2>$1</h2>', "yourtext");
     $this->showTextbox2();
     $wgOut->addReturnTo($this->getContextTitle(), array('action' => 'edit'));
 }
示例#8
0
 protected function getLastDiff()
 {
     // Shortcuts
     $title = $this->handle->getTitle();
     $latestRevId = $title->getLatestRevID();
     $previousRevId = $title->getPreviousRevisionID($latestRevId);
     $latestRev = Revision::newFromTitle($title, $latestRevId);
     $previousRev = Revision::newFromTitle($title, $previousRevId);
     $diffText = '';
     if ($latestRev && $previousRev) {
         $latest = $latestRev->getText();
         $previous = $previousRev->getText();
         if ($previous !== $latest) {
             $diff = new DifferenceEngine();
             if (method_exists('DifferenceEngine', 'setTextLanguage')) {
                 $diff->setTextLanguage($this->getTargetLanguage());
             }
             $diff->setText($previous, $latest);
             $diff->setReducedLineNumbers();
             $diff->showDiffStyle();
             $diffText = $diff->getDiff(false, false);
         }
     }
     if (!$latestRev) {
         return null;
     }
     global $wgUser;
     $user = $latestRev->getUserText(Revision::FOR_THIS_USER, $wgUser);
     $comment = $latestRev->getComment();
     if ($diffText === '') {
         if (strval($comment) !== '') {
             $text = wfMessage('translate-dynagroup-byc', $user, $comment)->escaped();
         } else {
             $text = wfMessage('translate-dynagroup-by', $user)->escaped();
         }
     } else {
         if (strval($comment) !== '') {
             $text = wfMessage('translate-dynagroup-lastc', $user, $comment)->escaped();
         } else {
             $text = wfMessage('translate-dynagroup-last', $user)->escaped();
         }
     }
     return TranslateUtils::fieldset($text, $diffText, array('class' => 'mw-sp-translate-latestchange'));
 }
示例#9
0
 /**
  * Get a diff between the current contents of the edit box and the
  * version of the page we're editing from.
  *
  * If this is a section edit, we'll replace the section as for final
  * save and then make a comparison.
  *
  * @return string HTML
  */
 function getDiff()
 {
     $oldtext = $this->mArticle->fetchContent();
     $newtext = $this->mArticle->replaceSection($this->section, $this->textbox1, $this->summary, $this->edittime);
     $newtext = $this->mArticle->preSaveTransform($newtext);
     $oldtitle = wfMsgExt('currentrev', array('parseinline'));
     $newtitle = wfMsgExt('yourtext', array('parseinline'));
     if ($oldtext !== false || $newtext != '') {
         $de = new DifferenceEngine($this->mTitle);
         $de->setText($oldtext, $newtext);
         $difftext = $de->getDiff($oldtitle, $newtitle);
     } else {
         $difftext = '';
     }
     return '<div id="wikiDiff">' . $difftext . '</div>';
 }
示例#10
0
 protected function showConflict()
 {
     if (wfRunHooks('EditPageBeforeConflictDiff', array(&$this, &$this->out))) {
         // diff
         $this->out->addHtml('<div id="diff">');
         $this->out->wrapWikiMsg('<h2>$1</h2>', 'editpagelayout-diff-header');
         $de = new DifferenceEngine($this->mTitle);
         $de->setText($this->textbox2, $this->textbox1);
         $de->showDiff(wfMsg("yourtext"), wfMsg("storedversion"));
         $this->out->addHtml('</div>');
         // user's edit
         $this->out->addHtml('<div id="myedit">');
         $this->out->wrapWikiMsg('<h2>$1</h2>', 'editpagelayout-myedit-header');
         $this->showTextbox2();
         $this->out->addHtml('</div>');
     }
 }
示例#11
0
 /**
  * Get a diff between the current contents of the edit box and the
  * version of the page we're editing from.
  *
  * If this is a section edit, we'll replace the section as for final
  * save and then make a comparison.
  */
 function showDiff()
 {
     $oldtext = $this->mArticle->fetchContent();
     $newtext = $this->mArticle->replaceSection($this->section, $this->textbox1, $this->summary, $this->edittime);
     wfRunHooks('EditPageGetDiffText', array($this, &$newtext));
     $newtext = $this->mArticle->preSaveTransform($newtext);
     $oldtitle = wfMsgExt('currentrev', array('parseinline'));
     $newtitle = wfMsgExt('yourtext', array('parseinline'));
     if ($oldtext !== false || $newtext != '') {
         $de = new DifferenceEngine($this->mTitle);
         $de->setText($oldtext, $newtext);
         $difftext = $de->getDiff($oldtitle, $newtitle);
         $de->showDiffStyle();
     } else {
         $difftext = '';
     }
     global $wgOut;
     $wgOut->addHTML('<div id="wikiDiff">' . $difftext . '</div>');
 }
    function showEditForm($formCallback = null)
    {
        global $wgOut, $wgUser, $wgLang, $wgContLang, $wgMaxArticleSize;
        // print "call SHOW EDIT FORM";
        if (!isset($this->stripped_edit_text)) {
            $this->stripped_edit_text = '';
        }
        $fname = 'EditPageAjax::showEditForm';
        wfProfileIn($fname);
        $closeFormHtml = '';
        // check if we are in the MVD namespace (and need to use templates for edits:)
        if ($this->mTitle->getNamespace() == MV_NS_MVD) {
            // get display type get mvTitle if not set
            if (!isset($this->article->mvTitle)) {
                $this->mvTitle = new MV_Title($this->mTitle->getDBkey());
            }
            $editFormType = strtolower($this->mvTitle->getMvdTypeKey());
        } else {
            // check if its seq type:
            if ($this->mvd_id == 'seq') {
                $editFormType = 'seq';
            } else {
                $editFormType = 'default';
            }
        }
        switch ($editFormType) {
            case 'ht_en':
                $this->do_pre_htEdit();
                $closeFormHtml = $this->do_post_HtEdit();
                break;
            case 'anno_en':
                $this->loadEditText();
                // set the default action so save page:
                $wgOut->addHTML($this->getAjaxForm());
                // add in adjust html if present:
                $wgOut->addHTML($this->adj_html);
                break;
            case 'seq':
                $wgOut->addHTML(wfMsg('mv_edit_sequence_desc_help'));
                if ($this->mArticle->mTitle->exists()) {
                    $this->stripped_edit_text = $this->mArticle->getPageContent();
                } else {
                    $this->stripped_edit_text = '';
                }
                $wgOut->addHTML($this->getAjaxForm());
                break;
            default:
                $this->loadEditText();
                // set the default action so save page:
                $wgOut->addHTML($this->getAjaxForm());
                break;
        }
        $sk = $wgUser->getSkin();
        // wfRunHooks( 'EditPage::showEditForm:initial', array( &$this ) ) ;
        // $wgOut->setRobotpolicy( 'noindex,nofollow' );
        # Enabled article-related sidebar, top links, etc.
        $wgOut->setArticleRelated(true);
        if ($this->isConflict) {
            $s = wfMsg('editconflict', $this->mTitle->getPrefixedText());
            $wgOut->setPageTitle($s);
            $wgOut->addWikiText(wfMsg('explainconflict'));
            $this->textbox2 = $this->textbox1;
            $this->textbox1 = $this->stripped_edit_text;
            $this->edittime = $this->mArticle->getTimestamp();
        } else {
            if ($this->section != '') {
                if ($this->section == 'new') {
                    $s = wfMsg('editingcomment', $this->mTitle->getPrefixedText());
                } else {
                    $s = wfMsg('editingsection', $this->mTitle->getPrefixedText());
                    $matches = array();
                    if (!$this->summary && !$this->preview && !$this->diff) {
                        preg_match("/^(=+)(.+)\\1/mi", $this->stripped_edit_text, $matches);
                        if (!empty($matches[2])) {
                            $this->summary = "/* " . trim($matches[2]) . " */ ";
                        }
                    }
                }
            } else {
                $s = wfMsg('editing', $this->mTitle->getPrefixedText());
            }
            // $wgOut->addHTML($s);
            // $wgOut->setPageTitle( $s );
            if ($this->missingComment) {
                $wgOut->addWikiText(wfMsg('missingcommenttext'));
            }
            if ($this->missingSummary && $this->section != 'new') {
                $wgOut->addWikiText(wfMsg('missingsummary'));
            }
            if ($this->missingSummary && $this->section == 'new') {
                $wgOut->addWikiText(wfMsg('missingcommentheader'));
            }
            if (!$this->hookError == '') {
                $wgOut->addWikiText($this->hookError);
            }
            if (!$this->checkUnicodeCompliantBrowser()) {
                $wgOut->addWikiText(wfMsg('nonunicodebrowser'));
            }
            if (isset($this->mArticle) && isset($this->mArticle->mRevision)) {
                // Let sysop know that this will make private content public if saved
                if ($this->mArticle->mRevision->isDeleted(Revision::DELETED_TEXT)) {
                    $wgOut->wrapWikiMsg("<div class='mw-warning plainlinks'>\n\$1</div>\n", 'rev-deleted-text-view');
                }
                if (!$this->mArticle->mRevision->isCurrent()) {
                    $this->mArticle->setOldSubtitle($this->mArticle->mRevision->getId());
                    $wgOut->addWikiText(wfMsg('editingold'));
                }
            }
        }
        if (wfReadOnly()) {
            $wgOut->addWikiText(wfMsg('readonlywarning'));
        } elseif ($wgUser->isAnon() && $this->formtype != 'preview') {
            $wgOut->addWikiText(wfMsg('anoneditwarning'));
        } else {
            if ($this->isCssJsSubpage && $this->formtype != 'preview') {
                # Check the skin exists
                if (!$this->isWrongCaseCssJsPage) {
                    $wgOut->addWikiText(wfMsg('usercssjsyoucanpreview'));
                } else {
                    $wgOut->addWikiText(wfMsg('userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage()));
                }
            }
        }
        if ($this->mTitle->getNamespace() == NS_MEDIAWIKI) {
            # Show a warning if editing an interface message
            $wgOut->addWikiText(wfMsg('editinginterface'));
        } elseif ($this->mTitle->isProtected('edit')) {
            # Is the title semi-protected?
            if ($this->mTitle->isSemiProtected()) {
                $notice = wfMsg('semiprotectedpagewarning');
                if (wfEmptyMsg('semiprotectedpagewarning', $notice) || $notice == '-') {
                    $notice = '';
                }
            } else {
                # Then it must be protected based on static groups (regular)
                $notice = wfMsg('protectedpagewarning');
            }
            $wgOut->addWikiText($notice);
        }
        if ($this->mTitle->isCascadeProtected()) {
            # Is this page under cascading protection from some source pages?
            list($cascadeSources, ) = $this->mTitle->getCascadeProtectionSources();
            if (count($cascadeSources) > 0) {
                # Explain, and list the titles responsible
                $notice = wfMsgExt('cascadeprotectedwarning', array('parsemag'), count($cascadeSources)) . "\n";
                foreach ($cascadeSources as $id => $page) {
                    $notice .= '* [[:' . $page->getPrefixedText() . "]]\n";
                }
            }
            $wgOut->addWikiText($notice);
        }
        if ($this->kblength === false) {
            $this->kblength = (int) (strlen($this->stripped_edit_text) / 1024);
        }
        if ($this->tooBig || $this->kblength > $wgMaxArticleSize) {
            $wgOut->addWikiText(wfMsg('longpageerror', $wgLang->formatNum($this->kblength), $wgMaxArticleSize));
        } elseif ($this->kblength > 29) {
            $wgOut->addWikiText(wfMsg('longpagewarning', $wgLang->formatNum($this->kblength)));
        }
        # need to parse the preview early so that we know which templates are used,
        # otherwise users with "show preview after edit box" will get a blank list
        if ($this->formtype == 'preview') {
            $previewOutput = $this->getPreviewText();
        }
        if ($wgUser->getOption('previewontop')) {
            if ('preview' == $this->formtype) {
                $this->showPreview($previewOutput);
            } else {
                $wgOut->addHTML('<div id="wikiPreview_' . htmlspecialchars($this->mvd_id) . '"></div>');
            }
            if ('diff' == $this->formtype) {
                $this->showDiff();
            }
        }
        $wgOut->addHTML($this->basic_html);
        $wgOut->addHTML('<div style="display:inline" class="mv_advanced_edit"><br>');
        // $rows = $wgUser->getIntOption( 'rows' );
        // $cols = $wgUser->getIntOption( 'cols' );
        // for ajax short edit area:
        $rows = 3;
        $cols = 40;
        $ew = $wgUser->getOption('editwidth');
        if ($ew) {
            $ew = " style=\"width:100%\"";
        } else {
            $ew = '';
        }
        // do ajax action:
        // $q = 'action=ajax';
        # if ( "no" == $redirect ) { $q .= "&redirect=no"; }
        // $action = $this->mTitle->escapeLocalURL( $q );
        if ($editFormType == 'seq') {
            $summary = wfMsg('mv_seq_summary');
        } else {
            $summary = wfMsg('summary');
        }
        $subject = wfMsg('subject');
        if ($this->mvd_id == 'seq') {
            $cancel = $sk->makeKnownLinkObj($this->mTitle, wfMsgExt('cancel', array('parseinline')));
            $edithelpurl = Skin::makeInternalOrExternalUrl(wfMsgForContent('mv_edithelpsequence'));
        } else {
            $cancel = '<a href="javascript:mv_disp_mvd(\'' . $this->mTitle->getDBkey() . '\',\'' . $this->mvd_id . '\');">' . wfMsgExt('cancel', array('parseinline')) . '</a>';
            $edithelpurl = Skin::makeInternalOrExternalUrl(wfMsgForContent('edithelppage'));
        }
        $edithelp = '<a target="helpwindow" href="' . $edithelpurl . '">' . htmlspecialchars(wfMsg('edithelp')) . '</a> ' . htmlspecialchars(wfMsg('newwindow'));
        global $wgRightsText;
        // copy right here is too verbose for a ajax window
        /*$copywarn = "<div id=\"editpage-copywarn\">\n" .
        			wfMsg( $wgRightsText ? 'copyrightwarning' : 'copyrightwarning2',
        				'[[' . wfMsgForContent( 'copyrightpage' ) . ']]',
        				$wgRightsText ) . "\n</div>";
        		*/
        if ($wgUser->getOption('showtoolbar') and !$this->isCssJsSubpage) {
            # prepare toolbar for edit buttons
            $toolbar = EditPage::getEditToolbar();
        } else {
            $toolbar = '';
        }
        // activate checkboxes if user wants them to be always active
        if (!$this->preview && !$this->diff) {
            # Sort out the "watch" checkbox
            if ($wgUser->getOption('watchdefault')) {
                # Watch all edits
                $this->watchthis = true;
            } elseif ($wgUser->getOption('watchcreations') && !$this->mTitle->exists()) {
                # Watch creations
                $this->watchthis = true;
            } elseif ($this->mTitle->userIsWatching()) {
                # Already watched
                $this->watchthis = true;
            }
            if ($wgUser->getOption('minordefault')) {
                $this->minoredit = true;
            }
        }
        $wgOut->addHTML($this->editFormPageTop);
        $wgOut->addHTML($this->editFormTextTop);
        # if this is a comment, show a subject line at the top, which is also the edit summary.
        # Otherwise, show a summary field at the bottom
        $summarytext = htmlspecialchars($wgContLang->recodeForEdit($this->summary));
        # FIXME
        if ($this->section == 'new') {
            $commentsubject = "<br /><span id='wpSummaryLabel'><label for='wpSummary'>{$subject}:</label></span>\n<div class='editOptions'>\n<input tabindex='1' type='text' value=\"{$summarytext}\" name='wpSummary' id='wpSummary' maxlength='200' size='40' /><br />";
            $editsummary = '';
            $subjectpreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">" . wfMsg('subject-preview') . ':' . $sk->commentBlock($this->summary, $this->mTitle) . "</div>\n" : '';
            $summarypreview = '';
        } else {
            $commentsubject = '';
            $editsummary = "<br /><span id='wpSummaryLabel'><label for='wpSummary'>{$summary}:</label></span>\n<div class='editOptions'>\n<input tabindex='2' type='text' value=\"{$summarytext}\" name='wpSummary' id='wpSummary' maxlength='200' size='40' /><br />";
            $summarypreview = $summarytext && $this->preview ? "<div class=\"mw-summary-preview\">" . wfMsg('summary-preview') . ':' . $sk->commentBlock($this->summary, $this->mTitle) . "</div>\n" : '';
            $subjectpreview = '';
        }
        $templates = $this->preview || $this->section != '' ? $this->mPreviewTemplates : $this->mArticle->getUsedTemplates();
        $formattedtemplates = $sk->formatTemplates($templates, $this->preview, $this->section != '');
        global $wgUseMetadataEdit;
        if ($wgUseMetadataEdit) {
            $metadata = $this->mMetaData;
            $metadata = htmlspecialchars($wgContLang->recodeForEdit($metadata));
            $top = wfMsgWikiHtml('metadata_help');
            $metadata = $top . "<textarea name='metadata' rows='3' cols='{$cols}'{$ew}>{$metadata}</textarea>";
        } else {
            $metadata = "";
        }
        $hidden = '';
        $recreate = '';
        if ($this->deletedSinceEdit) {
            if ('save' != $this->formtype) {
                $wgOut->addWikiText(wfMsg('deletedwhileediting'));
            } else {
                // Hide the toolbar and edit area, use can click preview to get it back
                // Add an confirmation checkbox and explanation.
                $toolbar = '';
                $hidden = 'type="hidden" style="display:none;"';
                $recreate = $wgOut->parse(wfMsg('confirmrecreate', $this->lastDelete->user_name, $this->lastDelete->log_comment));
                $recreate .= "<br /><input tabindex='1' type='checkbox' value='1' name='wpRecreate' id='wpRecreate' />" . "<label for='wpRecreate' title='" . wfMsg('tooltip-recreate') . "'>" . wfMsg('recreate') . "</label>";
            }
        }
        $tabindex = 2;
        $checkboxes = self::getCheckboxes($tabindex, $sk, array('minor' => $this->minoredit, 'watch' => $this->watchthis));
        $checkboxhtml = implode($checkboxes, "\n");
        $button_action = 'mv_do_ajax_form_submit(\'' . $this->mvd_id . '\', \'%s\');';
        $buttons = $this->getEditButtons($tabindex, $button_action);
        $buttonshtml = implode($buttons, "\n");
        $safemodehtml = $this->checkUnicodeCompliantBrowser() ? '' : Html::Hidden('safemode', '1');
        $wgOut->addHTML(<<<END
{$toolbar}
END
);
        // remove form because set earlier
        // <form id="editform" name="editform" method="post" action="$action" enctype="multipart/form-data">
        if (is_callable($formCallback)) {
            call_user_func_array($formCallback, array(&$wgOut));
        }
        wfRunHooks('EditPage::showEditForm:fields', array(&$this, &$wgOut));
        // Put these up at the top to ensure they aren't lost on early form submission
        $wgOut->addHTML("\n<input type='hidden' value=\"" . htmlspecialchars($this->section) . "\" name=\"wpSection\" />\n<input type='hidden' value=\"{$this->starttime}\" name=\"wpStarttime\" />\n\n<input type='hidden' value=\"{$this->edittime}\" name=\"wpEdittime\" />\n\n<input type='hidden' value=\"{$this->scrolltop}\" name=\"wpScrolltop\" id=\"wpScrolltop\" />\n");
        $wgOut->addHTML(<<<END
{$recreate}
{$commentsubject}
{$subjectpreview}
<textarea class="mv_ajax_textarea" tabindex='1' accesskey="," name="wpTextbox1" id="wpTextbox1" rows='{$rows}'
cols='{$cols}' {$ew} {$hidden}>
END
 . htmlspecialchars($this->safeUnicodeOutput($this->stripped_edit_text)) . "\n</textarea>\n\t\t");
        // close advanced display_edit div
        $wgOut->addHTML("</div>");
        // $wgOut->addWikiText( $copywarn );
        $wgOut->addHTML($this->editFormTextAfterWarn);
        $separator = wfMsgExt('pipe-separator', 'escapenoentities');
        $wgOut->addHTML("\n{$metadata}\n{$editsummary}\n{$summarypreview}\n{$checkboxhtml}\n{$safemodehtml}\n");
        $wgOut->addHTML("<div class='editButtons'>\n{$buttonshtml}\n\t<span class='editHelp'>{$cancel}{$separator}{$edithelp}</span>\n</div><!-- editButtons -->\n</div><!-- editOptions -->");
        $wgOut->addHTML('<div class="mw-editTools">');
        $wgOut->addWikiText(wfMsgForContent('edittools'));
        $wgOut->addHTML('</div>');
        $wgOut->addHTML($this->editFormTextAfterTools);
        $wgOut->addHTML("\n<div class='templatesUsed'>\n{$formattedtemplates}\n</div>\n");
        /**
         * To make it harder for someone to slip a user a page
         * which submits an edit form to the wiki without their
         * knowledge, a random token is associated with the login
         * session. If it's not passed back with the submission,
         * we won't save the page, or render user JavaScript and
         * CSS previews.
         *
         * For anon editors, who may not have a session, we just
         * include the constant suffix to prevent editing from
         * broken text-mangling proxies.
         */
        $token = htmlspecialchars($wgUser->editToken());
        $wgOut->addHTML("\n<input type='hidden' value=\"{$token}\" name=\"wpEditToken\" />\n");
        # If a blank edit summary was previously provided, and the appropriate
        # user preference is active, pass a hidden tag here. This will stop the
        # user being bounced back more than once in the event that a summary
        # is not required.
        if ($this->missingSummary) {
            $wgOut->addHTML("<input type=\"hidden\" name=\"wpIgnoreBlankSummary\" value=\"1\" />\n");
        }
        # For a bit more sophisticated detection of blank summaries, hash the
        # automatic one and pass that in a hidden field.
        $autosumm = $this->autoSumm ? $this->autoSumm : md5($this->summary);
        $wgOut->addHTML(Html::Hidden('wpAutoSummary', $autosumm));
        if ($this->isConflict) {
            $wgOut->addWikiText('==' . wfMsg("yourdiff") . '==');
            $de = new DifferenceEngine($this->mTitle);
            $de->setText($this->textbox2, $this->stripped_edit_text);
            $de->showDiff(wfMsg("yourtext"), wfMsg("storedversion"));
            $wgOut->addWikiText('==' . wfMsg("yourtext") . '==');
            $wgOut->addHTML("<textarea tabindex=6 id='wpTextbox2' name=\"wpTextbox2\" rows='{$rows}' cols='{$cols}' wrap='virtual'>" . htmlspecialchars($this->safeUnicodeOutput($this->textbox2)) . "\n</textarea>");
        }
        $wgOut->addHTML($this->editFormTextBottom);
        $wgOut->addHTML("</form>\n");
        if (!$wgUser->getOption('previewontop')) {
            if ($this->formtype == 'preview') {
                $this->showPreview($previewOutput);
            } else {
                $wgOut->addHTML('<div id="wikiPreview"></div>');
            }
            if ($this->formtype == 'diff') {
                $this->showDiff();
            }
        }
        $wgOut->addHTML($closeFormHtml);
        wfProfileOut($fname);
    }
示例#13
0
 /**
  * Show an edit conflict. textbox1 is already shown in showEditForm().
  * If you want to use another entry point to this function, be careful.
  */
 protected function showConflict()
 {
     global $wgOut;
     if (wfRunHooks('EditPageBeforeConflictDiff', array(&$this, &$wgOut))) {
         $wgOut->wrapWikiMsg('<h2>$1</h2>', "yourdiff");
         $de = new DifferenceEngine($this->mArticle->getContext());
         $de->setText($this->textbox2, $this->textbox1);
         $de->showDiff(wfMessage('yourtext')->parse(), wfMessage('storedversion')->text());
         $wgOut->wrapWikiMsg('<h2>$1</h2>', "yourtext");
         $this->showTextbox2();
     }
 }
示例#14
0
 /**
  * @todo Very long code block; split up.
  *
  * @param $group MessageGroup
  * @param $code
  */
 public function importForm($group, $code)
 {
     $this->setSubtitle($group, $code);
     $formParams = array('method' => 'post', 'action' => $this->getTitle()->getFullURL(array('group' => $group->getId())), 'class' => 'mw-translate-manage');
     global $wgRequest, $wgLang;
     if ($wgRequest->wasPosted() && $wgRequest->getBool('process', false) && $this->user->isAllowed('translate-manage') && $this->user->matchEditToken($wgRequest->getVal('token'))) {
         $process = true;
     } else {
         $process = false;
     }
     $this->out->addHTML(Xml::openElement('form', $formParams) . Html::hidden('title', $this->getTitle()->getPrefixedText()) . Html::hidden('token', $this->user->editToken()) . Html::hidden('group', $group->getId()) . Html::hidden('process', 1));
     // BEGIN
     $cache = new MessageGroupCache($group, $code);
     if (!$cache->exists() && $code === 'en') {
         $cache->create();
     }
     $collection = $group->initCollection($code);
     $collection->loadTranslations();
     $diff = new DifferenceEngine();
     $diff->showDiffStyle();
     $diff->setReducedLineNumbers();
     $ignoredMessages = $collection->getTags('ignored');
     if (!is_array($ignoredMessages)) {
         $ignoredMessages = array();
     }
     $messages = $group->load($code);
     $changed = array();
     foreach ($messages as $key => $value) {
         // ignored? ignore!
         if (in_array($key, $ignoredMessages)) {
             continue;
         }
         $fuzzy = $old = false;
         if (isset($collection[$key])) {
             $old = $collection[$key]->translation();
         }
         // No changes at all, ignore.
         if (str_replace(TRANSLATE_FUZZY, '', $old) === $value) {
             continue;
         }
         if ($old === false) {
             $name = wfMsgHtml('translate-manage-import-new', '<code style="font-weight:normal;">' . htmlspecialchars($key) . '</code>');
             $text = TranslateUtils::convertWhiteSpaceToHTML($value);
             $changed[] = MessageWebImporter::makeSectionElement($name, 'new', $text);
         } else {
             if (TranslateEditAddons::hasFuzzyString($old)) {
                 // NO-OP
             } else {
                 $transTitle = MessageWebImporter::makeTranslationTitle($group, $key, $code);
                 if (TranslateEditAddons::isFuzzy($transTitle)) {
                     $old = TRANSLATE_FUZZY . $old;
                 }
             }
             $diff->setText($old, $value);
             $text = $diff->getDiff('', '');
             $type = 'changed';
             if ($process) {
                 if (!count($changed)) {
                     $changed[] = '<ul>';
                 }
                 $action = $wgRequest->getVal(MessageWebImporter::escapeNameForPHP("action-{$type}-{$key}"));
                 if ($action === null) {
                     $message = wfMsgExt('translate-manage-inconsistent', 'parseinline', wfEscapeWikiText("action-{$type}-{$key}"));
                     $changed[] = "<li>{$message}</li></ul>";
                     $process = false;
                 } else {
                     // Initialise processing time counter.
                     if (!isset($this->time)) {
                         $this->time = wfTimestamp();
                     }
                     $fuzzybot = FuzzyBot::getUser();
                     $message = MessageWebImporter::doAction($action, $group, $key, $code, $value, '', $fuzzybot, EDIT_FORCE_BOT);
                     $key = array_shift($message);
                     $params = $message;
                     $message = wfMsgExt($key, 'parseinline', $params);
                     $changed[] = "<li>{$message}</li>";
                     if ($this->checkProcessTime()) {
                         $process = false;
                         $duration = $wgLang->formatNum($this->processingTime);
                         $message = wfMsgExt('translate-manage-toolong', 'parseinline', $duration);
                         $changed[] = "<li>{$message}</li></ul>";
                     }
                     continue;
                 }
             }
             if ($code !== 'en') {
                 $actions = array('import', 'conflict', 'ignore');
             } else {
                 $actions = array('import', 'fuzzy', 'ignore');
             }
             $act = array();
             if ($this->user->isAllowed('translate-manage')) {
                 $defaction = $fuzzy ? 'conflict' : 'import';
                 foreach ($actions as $action) {
                     $label = wfMsg("translate-manage-action-{$action}");
                     $name = MessageWebImporter::escapeNameForPHP("action-{$type}-{$key}");
                     $selected = $wgRequest->getVal($name, $defaction);
                     $id = Sanitizer::escapeId("action-{$key}-{$action}");
                     $act[] = Xml::radioLabel($label, $name, $action, $id, $action === $selected);
                 }
             }
             $name = wfMsg('translate-manage-import-diff', '<code style="font-weight:normal;">' . htmlspecialchars($key) . '</code>', implode(' ', $act));
             $changed[] = MessageWebImporter::makeSectionElement($name, $type, $text);
         }
     }
     if (!$process) {
         $collection->filter('hastranslation', false);
         $keys = $collection->getMessageKeys();
         $diff = array_diff($keys, array_keys($messages));
         foreach ($diff as $s) {
             $name = wfMsgHtml('translate-manage-import-deleted', '<code style="font-weight:normal;">' . htmlspecialchars($s) . '</code>');
             $text = TranslateUtils::convertWhiteSpaceToHTML($collection[$s]->translation());
             $changed[] = MessageWebImporter::makeSectionElement($name, 'deleted', $text);
         }
     }
     if ($process || !count($changed) && $code !== 'en') {
         if (!count($changed)) {
             $this->out->addWikiMsg('translate-manage-nochanges-other');
         }
         if (!count($changed) || strpos($changed[count($changed) - 1], '<li>') !== 0) {
             $changed[] = '<ul>';
         }
         $cache->create();
         $message = wfMsgExt('translate-manage-import-rebuild', 'parseinline');
         $changed[] = "<li>{$message}</li>";
         $message = wfMsgExt('translate-manage-import-done', 'parseinline');
         $changed[] = "<li>{$message}</li></ul>";
         $this->out->addHTML(implode("\n", $changed));
     } else {
         // END
         if (count($changed)) {
             if ($code === 'en') {
                 $this->out->addWikiMsg('translate-manage-intro-en');
             } else {
                 $lang = TranslateUtils::getLanguageName($code, false, $wgLang->getCode());
                 $this->out->addWikiMsg('translate-manage-intro-other', $lang);
             }
             $this->out->addHTML(Html::hidden('language', $code));
             $this->out->addHTML(implode("\n", $changed));
             if ($this->user->isAllowed('translate-manage')) {
                 $this->out->addHTML(Xml::submitButton(wfMsg('translate-manage-submit')));
             }
         } elseif ($this->user->isAllowed('translate-manage')) {
             $cache->create();
             // Update timestamp
             $this->out->addWikiMsg('translate-manage-nochanges');
         }
     }
     $this->out->addHTML('</form>');
     if ($code === 'en') {
         $this->doModLangs($group);
     } else {
         $this->out->addHTML('<p>' . $this->skin->link($this->getTitle(), wfMsgHtml('translate-manage-return-to-group'), array(), array('group' => $group->getId())) . '</p>');
     }
 }
示例#15
0
    /**
     * Send the edit form and related headers to $wgOut
     * @param $formCallback Optional callable that takes an OutputPage
     *                      parameter; will be called during form output
     *                      near the top, for captchas and the like.
     */
    function showEditForm($formCallback = null)
    {
        global $wgOut, $wgUser, $wgLang, $wgContLang, $wgMaxArticleSize;
        $fname = 'EditPage::showEditForm';
        wfProfileIn($fname);
        $sk =& $wgUser->getSkin();
        wfRunHooks('EditPage::showEditForm:initial', array(&$this));
        $wgOut->setRobotpolicy('noindex,nofollow');
        # Enabled article-related sidebar, toplinks, etc.
        $wgOut->setArticleRelated(true);
        if ($this->isConflict) {
            $s = wfMsg('editconflict', $this->mTitle->getPrefixedText());
            $wgOut->setPageTitle("Testing something" . $s);
            $wgOut->addWikiText(wfMsg('explainconflict'));
            $this->textbox2 = $this->textbox1;
            $this->textbox1 = $this->mArticle->getContent();
            $this->edittime = $this->mArticle->getTimestamp();
        } else {
            if ($this->section != '') {
                if ($this->section == 'new') {
                    $s = wfMsg('editingcomment', $this->mTitle->getPrefixedText());
                } else {
                    $s = wfMsg('editingsection', $this->mTitle->getPrefixedText());
                    if (!$this->preview && !$this->diff) {
                        preg_match("/^(=+)(.+)\\1/mi", $this->textbox1, $matches);
                        if (!empty($matches[2])) {
                            $this->summary = "/* " . trim($matches[2]) . " */ ";
                        }
                    }
                }
            } else {
                $s = wfMsg('editing', $this->mTitle->getPrefixedText());
            }
            $wgOut->setPageTitle("Testing something" . $s);
            if ($this->missingComment) {
                $wgOut->addWikiText(wfMsg('missingcommenttext'));
            }
            if ($this->missingSummary) {
                $wgOut->addWikiText(wfMsg('missingsummary'));
            }
            if (!$this->checkUnicodeCompliantBrowser()) {
                $wgOut->addWikiText(wfMsg('nonunicodebrowser'));
            }
            if (isset($this->mArticle) && isset($this->mArticle->mRevision) && !$this->mArticle->mRevision->isCurrent()) {
                $this->mArticle->setOldSubtitle($this->mArticle->mRevision->getId());
                $wgOut->addWikiText(wfMsg('editingold'));
            }
        }
        if (wfReadOnly()) {
            $wgOut->addWikiText(wfMsg('readonlywarning'));
        } elseif ($wgUser->isAnon() && $this->formtype != 'preview') {
            $wgOut->addWikiText(wfMsg('anoneditwarning'));
        } else {
            if ($this->isCssJsSubpage && $this->formtype != 'preview') {
                # Check the skin exists
                if (!$this->isWrongCaseCssJsPage) {
                    $wgOut->addWikiText(wfMsg('usercssjsyoucanpreview'));
                } else {
                    $wgOut->addWikiText(wfMsg('userinvalidcssjstitle', $this->mTitle->getSkinFromCssJsSubpage()));
                }
            }
        }
        if ($this->mTitle->isProtected('edit')) {
            if ($this->mTitle->isSemiProtected()) {
                $notice = wfMsg('semiprotectedpagewarning');
                if (wfEmptyMsg('semiprotectedpagewarning', $notice) || $notice == '-') {
                    $notice = '';
                }
            } else {
                $notice = wfMsg('protectedpagewarning');
            }
            $wgOut->addWikiText($notice);
        }
        if ($this->kblength === false) {
            $this->kblength = (int) (strlen($this->textbox1) / 1024);
        }
        if ($this->tooBig || $this->kblength > $wgMaxArticleSize) {
            $wgOut->addWikiText(wfMsg('longpageerror', $wgLang->formatNum($this->kblength), $wgMaxArticleSize));
        } elseif ($this->kblength > 29) {
            $wgOut->addWikiText(wfMsg('longpagewarning', $wgLang->formatNum($this->kblength)));
        }
        $rows = $wgUser->getOption('rows');
        $cols = $wgUser->getOption('cols');
        $ew = $wgUser->getOption('editwidth');
        if ($ew) {
            $ew = " style=\"width:100%\"";
        } else {
            $ew = '';
        }
        $q = 'action=submit';
        #if ( "no" == $redirect ) { $q .= "&redirect=no"; }
        $action = $this->mTitle->escapeLocalURL($q);
        $summary = wfMsg('summary');
        $subject = wfMsg('subject');
        $minor = wfMsg('minoredit');
        $watchthis = wfMsg('watchthis');
        $cancel = $sk->makeKnownLink($this->mTitle->getPrefixedText(), wfMsg('cancel'));
        $edithelpurl = $sk->makeInternalOrExternalUrl(wfMsgForContent('edithelppage'));
        $edithelp = '<a target="helpwindow" href="' . $edithelpurl . '">' . htmlspecialchars(wfMsg('edithelp')) . '</a> ' . htmlspecialchars(wfMsg('newwindow'));
        global $wgRightsText;
        $copywarn = "<div id=\"editpage-copywarn\">\n" . wfMsg($wgRightsText ? 'copyrightwarning' : 'copyrightwarning2', '[[' . wfMsgForContent('copyrightpage') . ']]', $wgRightsText) . "\n</div>";
        if ($wgUser->getOption('showtoolbar') and !$this->isCssJsSubpage) {
            # prepare toolbar for edit buttons
            $toolbar = $this->getEditToolbar();
        } else {
            $toolbar = '';
        }
        // activate checkboxes if user wants them to be always active
        if (!$this->preview && !$this->diff) {
            # Sort out the "watch" checkbox
            if ($wgUser->getOption('watchdefault')) {
                # Watch all edits
                $this->watchthis = true;
            } elseif ($wgUser->getOption('watchcreations') && !$this->mTitle->exists()) {
                # Watch creations
                $this->watchthis = true;
            } elseif ($this->mTitle->userIsWatching()) {
                # Already watched
                $this->watchthis = true;
            }
            if ($wgUser->getOption('minordefault')) {
                $this->minoredit = true;
            }
        }
        $minoredithtml = '';
        if ($wgUser->isAllowed('minoredit')) {
            $minoredithtml = "<input tabindex='3' type='checkbox' value='1' name='wpMinoredit'" . ($this->minoredit ? " checked='checked'" : "") . " accesskey='" . wfMsg('accesskey-minoredit') . "' id='wpMinoredit' />" . "<label for='wpMinoredit' title='" . wfMsg('tooltip-minoredit') . "'>{$minor}</label>";
        }
        $watchhtml = '';
        if ($wgUser->isLoggedIn()) {
            $watchhtml = "<input tabindex='4' type='checkbox' name='wpWatchthis'" . ($this->watchthis ? " checked='checked'" : "") . " accesskey=\"" . htmlspecialchars(wfMsg('accesskey-watch')) . "\" id='wpWatchthis'  />" . "<label for='wpWatchthis' title=\"" . htmlspecialchars(wfMsg('tooltip-watch')) . "\">{$watchthis}</label>";
        }
        $checkboxhtml = $minoredithtml . $watchhtml;
        if ($wgUser->getOption('previewontop')) {
            if ('preview' == $this->formtype) {
                $this->showPreview();
            } else {
                $wgOut->addHTML('<div id="wikiPreview"></div>');
            }
            if ('diff' == $this->formtype) {
                $wgOut->addHTML($this->getDiff());
            }
        }
        # if this is a comment, show a subject line at the top, which is also the edit summary.
        # Otherwise, show a summary field at the bottom
        $summarytext = htmlspecialchars($wgContLang->recodeForEdit($this->summary));
        # FIXME
        if ($this->section == 'new') {
            $commentsubject = "<span id='wpSummaryLabel'><label for='wpSummary'>{$subject}:</label></span> <div class='editOptions'><input tabindex='1' type='text' value=\"{$summarytext}\" name='wpSummary' id='wpSummary' maxlength='200' size='60' /><br />";
            $editsummary = '';
        } else {
            $commentsubject = '';
            $editsummary = "<span id='wpSummaryLabel'><label for='wpSummary'>{$summary}:</label></span> <div class='editOptions'><input tabindex='2' type='text' value=\"{$summarytext}\" name='wpSummary' id='wpSummary' maxlength='200' size='60' /><br />";
        }
        # Set focus to the edit box on load, except on preview or diff, where it would interfere with the display
        if (!$this->preview && !$this->diff) {
            $wgOut->setOnloadHandler('document.editform.wpTextbox1.focus()');
        }
        $templates = $this->formatTemplates();
        global $wgUseMetadataEdit;
        if ($wgUseMetadataEdit) {
            $metadata = $this->mMetaData;
            $metadata = htmlspecialchars($wgContLang->recodeForEdit($metadata));
            $helppage = Title::newFromText(wfMsg("metadata_page"));
            $top = wfMsg('metadata', $helppage->getLocalURL());
            $metadata = $top . "<textarea name='metadata' rows='3' cols='{$cols}'{$ew}>{$metadata}</textarea>";
        } else {
            $metadata = "";
        }
        $hidden = '';
        $recreate = '';
        if ($this->deletedSinceEdit) {
            if ('save' != $this->formtype) {
                $wgOut->addWikiText(wfMsg('deletedwhileediting'));
            } else {
                // Hide the toolbar and edit area, use can click preview to get it back
                // Add an confirmation checkbox and explanation.
                $toolbar = '';
                $hidden = 'type="hidden" style="display:none;"';
                $recreate = $wgOut->parse(wfMsg('confirmrecreate', $this->lastDelete->user_name, $this->lastDelete->log_comment));
                $recreate .= "<br /><input tabindex='1' type='checkbox' value='1' name='wpRecreate' id='wpRecreate' />" . "<label for='wpRecreate' title='" . wfMsg('tooltip-recreate') . "'>" . wfMsg('recreate') . "</label>";
            }
        }
        $temp = array('id' => 'wpSave', 'name' => 'wpSave', 'type' => 'submit', 'tabindex' => '5', 'value' => wfMsg('savearticle'), 'accesskey' => wfMsg('accesskey-save'), 'title' => wfMsg('tooltip-save'));
        $buttons['save'] = Xml::element('input', $temp, '');
        $temp = array('id' => 'wpDiff', 'name' => 'wpDiff', 'type' => 'submit', 'tabindex' => '7', 'value' => wfMsg('showdiff'), 'accesskey' => wfMsg('accesskey-diff'), 'title' => wfMsg('tooltip-diff'));
        $buttons['diff'] = Xml::element('input', $temp, '');
        global $wgLivePreview;
        if ($wgLivePreview && $wgUser->getOption('uselivepreview')) {
            $temp = array('id' => 'wpPreview', 'name' => 'wpPreview', 'type' => 'submit', 'tabindex' => '6', 'value' => wfMsg('showpreview'), 'accesskey' => '', 'title' => wfMsg('tooltip-preview'), 'style' => 'display: none;');
            $buttons['preview'] = Xml::element('input', $temp, '');
            $temp = array('id' => 'wpLivePreview', 'name' => 'wpLivePreview', 'type' => 'submit', 'tabindex' => '6', 'value' => wfMsg('showlivepreview'), 'accesskey' => wfMsg('accesskey-preview'), 'title' => '', 'onclick' => $this->doLivePreviewScript());
            $buttons['live'] = Xml::element('input', $temp, '');
        } else {
            $temp = array('id' => 'wpPreview', 'name' => 'wpPreview', 'type' => 'submit', 'tabindex' => '6', 'value' => wfMsg('showpreview'), 'accesskey' => wfMsg('accesskey-preview'), 'title' => wfMsg('tooltip-preview'));
            $buttons['preview'] = Xml::element('input', $temp, '');
            $buttons['live'] = '';
        }
        $safemodehtml = $this->checkUnicodeCompliantBrowser() ? "" : "<input type='hidden' name=\"safemode\" value='1' />\n";
        $wgOut->addHTML(<<<END
<form id="editform" name="editform" method="post" action="{$action}"
enctype="multipart/form-data">
END
);
        if (is_callable($formCallback)) {
            call_user_func_array($formCallback, array(&$wgOut));
        }
        // Put these up at the top to ensure they aren't lost on early form submission
        $wgOut->addHTML("\n<input type='hidden' value=\"" . htmlspecialchars($this->section) . "\" name=\"wpSection\" />\n<input type='hidden' value=\"{$this->starttime}\" name=\"wpStarttime\" />\n\n<input type='hidden' value=\"{$this->edittime}\" name=\"wpEdittime\" />\n\n<input type='hidden' value=\"{$this->scrolltop}\" name=\"wpScrolltop\" id=\"wpScrolltop\" />\n");
        $this->addStructureFields();
        $wgOut->addHTML(<<<END
{$toolbar}
{$recreate}
{$commentsubject}
<textarea tabindex='1' accesskey="," name="wpTextbox1" id="wpTextbox1" rows='{$rows}'
cols='{$cols}'{$ew} {$hidden}>
END
 . htmlspecialchars($this->safeUnicodeOutput($this->textbox1)) . "\n</textarea>\n\t\t");
        $wgOut->addWikiText($copywarn);
        $wgOut->addHTML("\n{$metadata}\n{$editsummary}\n{$checkboxhtml}\n{$safemodehtml}\n");
        $wgOut->addHTML("\n<div class='editButtons'>\n\t{$buttons['save']}\n\t{$buttons['preview']}\n\t{$buttons['live']}\n\t{$buttons['diff']}\n\t<span class='editHelp'>{$cancel} | {$edithelp}</span>\n</div><!-- editButtons -->\n</div><!-- editOptions -->");
        $wgOut->addWikiText(wfMsgForContent('edittools'));
        $wgOut->addHTML("\n<div class='templatesUsed'>\n{$templates}\n</div>\n");
        if ($wgUser->isLoggedIn()) {
            /**
             * To make it harder for someone to slip a user a page
             * which submits an edit form to the wiki without their
             * knowledge, a random token is associated with the login
             * session. If it's not passed back with the submission,
             * we won't save the page, or render user JavaScript and
             * CSS previews.
             */
            $token = htmlspecialchars($wgUser->editToken());
            $wgOut->addHTML("\n<input type='hidden' value=\"{$token}\" name=\"wpEditToken\" />\n");
        }
        # If a blank edit summary was previously provided, and the appropriate
        # user preference is active, pass a hidden tag here. This will stop the
        # user being bounced back more than once in the event that a summary
        # is not required.
        if ($this->missingSummary) {
            $wgOut->addHTML("<input type=\"hidden\" name=\"wpIgnoreBlankSummary\" value=\"1\" />\n");
        }
        # For a bit more sophisticated detection of blank summaries, hash the
        # automatic one and pass that in a hidden field.
        $autosumm = $this->autoSumm ? $this->autoSumm : md5($this->summary);
        $wgOut->addHTML("<input type=\"hidden\" name=\"wpAutoSummary\" value=\"{$autosumm}\" />\n");
        if ($this->isConflict) {
            require_once "DifferenceEngine.php";
            $wgOut->addWikiText('==' . wfMsg("yourdiff") . '==');
            $de = new DifferenceEngine($this->mTitle);
            $de->setText($this->textbox2, $this->textbox1);
            $de->showDiff(wfMsg("yourtext"), wfMsg("storedversion"));
            $wgOut->addWikiText('==' . wfMsg("yourtext") . '==');
            $wgOut->addHTML("<textarea tabindex=6 id='wpTextbox2' name=\"wpTextbox2\" rows='{$rows}' cols='{$cols}' wrap='virtual'>" . htmlspecialchars($this->safeUnicodeOutput($this->textbox2)) . "\n</textarea>");
        }
        $wgOut->addHTML("</form>\n");
        if (!$wgUser->getOption('previewontop')) {
            if ($this->formtype == 'preview') {
                $this->showPreview();
            } else {
                $wgOut->addHTML('<div id="wikiPreview"></div>');
            }
            if ($this->formtype == 'diff') {
                $wgOut->addHTML($this->getDiff());
            }
        }
        wfProfileOut($fname);
    }
	/**
	 * Displays the sections and changes for the user to review
	 * @param $page TranslatablePage
	 * @param $sections array
	 */
	public function showPage( TranslatablePage $page, Array $sections ) {
		global $wgOut, $wgContLang;

		$wgOut->setSubtitle( $this->user->getSkin()->link( $page->getTitle() ) );
		$wgOut->addModules( 'ext.translate.special.pagetranslation' );

		$wgOut->addWikiMsg( 'tpt-showpage-intro' );

		$formParams = array(
			'method' => 'post',
			'action' => $this->getTitle()->getFullURL(),
			'class'  => 'mw-tpt-sp-markform',
		);

		$wgOut->addHTML(
			Xml::openElement( 'form', $formParams ) .
			Html::hidden( 'title', $this->getTitle()->getPrefixedText() ) .
			Html::hidden( 'revision', $page->getRevision() ) .
			Html::hidden( 'target', $page->getTitle()->getPrefixedtext() ) .
			Html::hidden( 'token', $this->user->editToken() )
		);

		$wgOut->wrapWikiMsg( '==$1==', 'tpt-sections-oldnew' );

		$diffOld = wfMsgHtml( 'tpt-diff-old' );
		$diffNew = wfMsgHtml( 'tpt-diff-new' );

		foreach ( $sections as $s ) {
			if ( $s->type === 'new' ) {
				$input = Xml::input( 'tpt-sect-' . $s->id, 15, $s->name );
				$name = wfMsgHtml( 'tpt-section-new', $input );
			} else {
				$name = wfMsgHtml( 'tpt-section', htmlspecialchars( $s->name ) );
			}

			if ( $s->type === 'changed' ) {
				$diff = new DifferenceEngine;
				if ( method_exists( 'DifferenceEngine', 'setTextLanguage' ) ) {
					$diff->setTextLanguage( $wgContLang );
				}
				$diff->setReducedLineNumbers();
				$diff->setText( $s->getOldText(), $s->getText() );
				$text = $diff->getDiff( $diffOld, $diffNew );
				$diffOld = $diffNew = null;
				$diff->showDiffStyle();

				$id = "tpt-sect-{$s->id}-action-nofuzzy";
				$text = Xml::checkLabel( wfMsg( 'tpt-action-nofuzzy' ), $id, $id, false ) . $text;
			} else {
				$text = TranslateUtils::convertWhiteSpaceToHTML( $s->getText() );
			}

			# For changed text, the language is set by $diff->setTextLanguage()
			$lang = $s->type === 'changed' ? null : $wgContLang;
			$wgOut->addHTML( MessageWebImporter::makeSectionElement( $name, $s->type, $text, $lang ) );
		}

		$deletedSections = $page->getParse()->getDeletedSections();
		if ( count( $deletedSections ) ) {
			$wgOut->wrapWikiMsg( '==$1==', 'tpt-sections-deleted' );

			foreach ( $deletedSections as $s ) {
				$name = wfMsgHtml( 'tpt-section-deleted', htmlspecialchars( $s->id ) );
				$text = TranslateUtils::convertWhiteSpaceToHTML( $s->getText() );
				$wgOut->addHTML( MessageWebImporter::makeSectionElement( $name, $s->type, $text, $wgContLang ) );
			}
		}

		// Display template changes if applicable
		if ( $page->getMarkedTag() !== false ) {
			$newTemplate = $page->getParse()->getTemplatePretty();
			$oldPage = TranslatablePage::newFromRevision( $page->getTitle(), $page->getMarkedTag() );
			$oldTemplate = $oldPage->getParse()->getTemplatePretty();

			if ( $oldTemplate !== $newTemplate ) {
				$wgOut->wrapWikiMsg( '==$1==', 'tpt-sections-template' );

				$diff = new DifferenceEngine;
				if ( method_exists( 'DifferenceEngine', 'setTextLanguage' ) ) {
					$diff->setTextLanguage( $wgContLang );
				}
				$diff->setText( $oldTemplate, $newTemplate );
				$text = $diff->getDiff( wfMsgHtml( 'tpt-diff-old' ), wfMsgHtml( 'tpt-diff-new' ) );
				$diff->showDiffStyle();
				$diff->setReducedLineNumbers();

				$contentParams = array( 'class' => 'mw-tpt-sp-content' );
				$wgOut->addHTML( Xml::tags( 'div', $contentParams, $text ) );
			}
		}

		$wgOut->addHTML(
			Xml::submitButton( wfMsg( 'tpt-submit' ) ) .
			Xml::closeElement( 'form' )
		);
	}