public function execute()
 {
     global $wgHooks;
     $out = $this->mSpecial->getOutput();
     if (!ModerationCanSkip::canSkip($this->moderator)) {
         // In order to merge, moderator must also be automoderated
         throw new ModerationError('moderation-merge-not-automoderated');
     }
     $dbw = wfGetDB(DB_MASTER);
     $row = $dbw->selectRow('moderation', array('mod_namespace AS namespace', 'mod_title AS title', 'mod_user_text AS user_text', 'mod_text AS text', 'mod_conflict AS conflict'), array('mod_id' => $this->id), __METHOD__);
     if (!$row) {
         throw new ModerationError('moderation-edit-not-found');
     }
     if (!$row->conflict) {
         throw new ModerationError('moderation-merge-not-needed');
     }
     $title = Title::makeTitle($row->namespace, $row->title);
     $article = new Article($title);
     ModerationEditHooks::$NewMergeID = $this->id;
     $editPage = new EditPage($article);
     $editPage->isConflict = true;
     $editPage->setContextTitle($title);
     $editPage->textbox1 = $row->text;
     $editPage->summary = wfMessage("moderation-merge-comment", $row->user_text)->inContentLanguage()->plain();
     $editPage->showEditForm();
 }
 public static function onApiCheckCanExecute($module, $user, &$message)
 {
     if ($module == 'upload' && !ModerationCanSkip::canSkip($user)) {
         $message = 'nouploadmodule';
         return false;
     }
     return true;
 }
 function formatResult($skin, $result)
 {
     global $wgModerationPreviewLink;
     wfProfileIn(__METHOD__);
     $len_change = $result->new_len - $result->old_len;
     if ($len_change > 0) {
         $len_change = '+' . $len_change;
     }
     $class = 'modline';
     $title = Title::makeTitle($result->namespace, $result->title);
     $line = '';
     $line .= '(' . $this->makeModerationLink('show', $result->id);
     if ($wgModerationPreviewLink) {
         $line .= ' | ' . $this->makeModerationLink('preview', $result->id);
     }
     $line .= ') . . ';
     if ($result->minor) {
         $line .= wfMessage('minoreditletter');
     }
     if ($result->bot) {
         $line .= wfMessage('boteditletter');
     }
     if ($result->new) {
         $line .= wfMessage('newpageletter');
     }
     $line .= ' ';
     $line .= Linker::link($title);
     $line .= ' ';
     $time = $this->getLanguage()->userTime($result->timestamp, $this->getUser());
     $date = $this->getLanguage()->userDate($result->timestamp, $this->getUser());
     $line .= Xml::tags('span', array('title' => $date), $time);
     $line .= ' . . ';
     $line .= ' (' . $len_change . ')';
     $line .= ' . . ';
     $line .= Linker::userLink($result->user, $result->user_text);
     if ($this->getUser()->isAllowed('moderation-checkuser')) {
         $line .= wfMessage('moderation-whois-link', $result->ip)->parse();
         # NOTE: no space before is on purpose, this link can be in <sup></sup> tags
     }
     $line .= ' (' . $result->comment . ')';
     if (!$result->merged_revid) {
         $line .= ' [';
         if ($result->conflict) {
             $class .= ' modconflict';
             if (ModerationCanSkip::canSkip($this->getUser())) {
                 // In order to merge, moderator must also be automoderated
                 $line .= $this->makeModerationLink('merge', $result->id);
             } else {
                 $line .= wfMessage('moderation-no-merge-link-not-automoderated');
             }
         } else {
             if (!$result->rejected || $result->timestamp > $this->earliestReapprovableTimestamp) {
                 $line .= $this->makeModerationLink('approve', $result->id);
             }
             # Note: you can use "Approve all" on rejected edit,
             # but it will only affect not-yet-rejected edits.
             # To avoid confusion, link "Approve all" is not shown for rejected edits.
             if (!$result->rejected) {
                 $line .= ' ';
                 $line .= $this->makeModerationLink('approveall', $result->id);
             }
         }
         if (!$result->rejected) {
             $line .= ' . . ';
             $line .= $this->makeModerationLink('reject', $result->id);
             $line .= ' ';
             $line .= $this->makeModerationLink('rejectall', $result->id);
         }
         $line .= ']';
     } else {
         $rev = Revision::newFromId($result->merged_revid);
         $line .= ' [' . Linker::link($rev ? $rev->getTitle() : $title, wfMessage('moderation-merged-link')->escaped(), array('title' => wfMessage('tooltip-moderation-merged-link')), array('diff' => $result->merged_revid), array('known', 'noclasses')) . ']';
     }
     $line .= ' . . [';
     $line .= $this->makeModerationLink($this->mblockCheck->isModerationBlocked($result->user_text) ? 'unblock' : 'block', $result->id);
     $line .= ']';
     if ($result->rejected) {
         $line .= ' . . ';
         if ($result->rejected_by_user) {
             $line .= wfMessage('moderation-rejected-by', Linker::userLink($result->rejected_by_user, $result->rejected_by_user_text))->text();
         } else {
             if ($result->rejected_auto) {
                 $line .= wfMessage('moderation-rejected-auto');
             }
         }
         if ($result->rejected_batch) {
             $line .= ' . . ' . wfMessage('moderation-rejected-batch');
         }
     }
     $html = Xml::tags('span', array('class' => $class), $line);
     wfProfileOut(__METHOD__);
     return $html;
 }
 public static function onPageContentSave(&$page, &$user, &$content, &$summary, $is_minor, $is_watch, $section, &$flags, &$status)
 {
     global $wgOut, $wgContLang;
     if (ModerationCanSkip::canSkip($user)) {
         return true;
     }
     $old_content = $page->getContent(Revision::RAW);
     // current revision's content
     $request = $user->getRequest();
     $title = $page->getTitle();
     $popts = ParserOptions::newFromUserAndLang($user, $wgContLang);
     $dbw = wfGetDB(DB_MASTER);
     $fields = array('mod_timestamp' => $dbw->timestamp(wfTimestampNow()), 'mod_user' => $user->getId(), 'mod_user_text' => $user->getName(), 'mod_cur_id' => $page->getId(), 'mod_namespace' => $title->getNamespace(), 'mod_title' => $title->getText(), 'mod_comment' => $summary, 'mod_minor' => $is_minor, 'mod_bot' => $flags & EDIT_FORCE_BOT, 'mod_new' => $page->exists() ? 0 : 1, 'mod_last_oldid' => $page->getLatest(), 'mod_ip' => $request->getIP(), 'mod_old_len' => $old_content ? $old_content->getSize() : 0, 'mod_new_len' => $content->getSize(), 'mod_header_xff' => $request->getHeader('X-Forwarded-For'), 'mod_header_ua' => $request->getHeader('User-Agent'), 'mod_text' => $content->preSaveTransform($title, $user, $popts)->getNativeData(), 'mod_preload_id' => ModerationPreload::generatePreloadId(), 'mod_preloadable' => 1);
     $mblockCheck = new ModerationBlockCheck();
     if ($mblockCheck->isModerationBlocked($user->getName())) {
         $fields['mod_rejected'] = 1;
         $fields['mod_rejected_by_user'] = 0;
         $fields['mod_rejected_by_user_text'] = wfMessage('Moderation block')->inContentLanguage()->text();
         $fields['mod_rejected_auto'] = 1;
         $fields['mod_preloadable'] = 1;
         # User can still edit this change, so that spammers won't notice that they are blocked
     }
     // Check if we need to update existing row (if this edit is by the same user to the same page)
     $row = ModerationPreload::loadUnmoderatedEdit($title);
     if (!$row) {
         $dbw->insert('moderation', $fields, __METHOD__);
         ModerationEditHooks::$LastInsertId = $dbw->insertId();
     } else {
         $section = $request->getVal('wpSection', $request->getVal('section'));
         if ($section) {
             #
             # We must recalculate $fields['mod_text'] here.
             # Otherwise if the user adds or modifies two (or more) different sections (in consequent edits),
             # then only modification to the last one will be saved,
             # because $content is [old content] PLUS [modified section from the edit].
             #
             # Difference between $index and $section:
             # $index: section number in $content. $index can't be "new". If $section was "new", then we need to recalculate $index.
             # $section: section number in $saved_content. $section can be "new". Used when calling replaceSection().
             #
             $index = $section;
             if ($section == 'new') {
                 #
                 # Parser doesn't allow to get the LAST section directly.
                 # We have to get the entire TOC - just for a single index.
                 #
                 $sections = $content->getParserOutput($title, null, null, false)->getSections();
                 $new_section_content = end($sections);
                 $index = $new_section_content['index'];
             }
             # $new_section_content is exactly what the user just wrote in the edit form (one section only).
             $new_section_content = $content->getSection($index);
             $saved_content = ContentHandler::makeContent($row->text, null, $content->getModel());
             $new_content = $saved_content->replaceSection($section, $new_section_content, '');
             $fields['mod_text'] = $new_content->preSaveTransform($title, $user, $popts)->getNativeData();
         }
         $dbw->update('moderation', $fields, array('mod_id' => $row->id), __METHOD__);
         ModerationEditHooks::$LastInsertId = $row->id;
     }
     // In case the caller treats "edit-hook-aborted" as an error.
     $dbw->commit();
     /*
     	We have queued this edit for moderation.
     	No need to save anything at this point.
     	Later (if approved) the edit will be saved via doEditContent().
     
     	Here we just redirect the users back to the page they edited
     	(as was the behavior for unmoderated edits).
     	Notification "Your edit was successfully sent for moderation"
     	will be shown by JavaScript.
     */
     $wgOut->redirect($title->getFullURL(array('modqueued' => 1)));
     return false;
 }