Beispiel #1
0
function wfMarkUndoneEditAsPatrolled()
{
    global $wgRequest;
    if ($wgRequest->getVal('wpUndoEdit', null) != null) {
        $oldid = $wgRequest->getVal('wpUndoEdit');
        // using db master to avoid db replication lag
        $dbr = wfGetDB(DB_MASTER);
        $rcid = $dbr->selectField('recentchanges', 'rc_id', array('rc_this_oldid' => $oldid));
        RecentChange::markPatrolled($rcid);
        PatrolLog::record($rcid, false);
    }
    return true;
}
Beispiel #2
0
    function execute($par)
    {
        global $wgRequest, $wgUser, $wgOut, $wgLang, $wgServer;
        wfLoadExtensionMessages('UserTalkTool');
        // CHECK FOR ADMIN STATUS
        if (!in_array('sysop', $wgUser->getGroups())) {
            $wgOut->setArticleRelated(false);
            $wgOut->setRobotpolicy('noindex,nofollow');
            $wgOut->errorpage('nosuchspecialpage', 'nospecialpagetext');
            return;
        }
        // MAKE SURE USER IS NOT BLOCKED
        if ($wgUser->isBlocked()) {
            $wgOut->blockedPage();
            return;
        }
        // CHECK FOR TARGET
        $target = isset($par) ? $par : $wgRequest->getVal('target');
        if ($target == null || $target == "") {
            $wgOut->addHTML('No target specified');
            return;
        }
        $dbw = wfGetDB(DB_MASTER);
        $dbr = wfGetDB(DB_SLAVE);
        $me = Title::makeTitle(NS_SPECIAL, "UserTalkTool");
        // PROCESS FORM
        //
        //
        if ($wgRequest->wasPosted()) {
            $wgOut->setArticleBodyOnly(true);
            $utmsg = $wgRequest->getVal('utmessage');
            if ($utmsg != "") {
                #$t = Title::newFromID($aid);
                $ts = wfTimestampNow();
                $user = $wgUser->getName();
                $real_name = User::whoIsReal($wgUser->getID());
                if ($real_name == "") {
                    $real_name = $user;
                }
                //User
                //
                //
                $utitem = $wgRequest->getVal('utuser');
                wfDebug("UTT: posting user: {$utitem}\n");
                wfDebug("UTT: by admin user: "******"\n");
                if ($utitem != "") {
                    // POST USER TALK PAGE
                    //
                    //
                    $text = "";
                    $aid = "";
                    $a = "";
                    $formattedComment = "";
                    $u = new User();
                    $u->setName($utitem);
                    $user_talk = $u->getTalkPage();
                    $dateStr = $wgLang->timeanddate(wfTimestampNow());
                    $formattedComment = wfMsg('postcomment_formatted_comment', $dateStr, $user, $real_name, mysql_real_escape_string($utmsg));
                    $aid = $user_talk->getArticleId();
                    if ($aid > 0) {
                        $r = Revision::newFromTitle($user_talk);
                        $text = $r->getText();
                    }
                    $a = new Article($user_talk);
                    $text .= "\n\n{$formattedComment}\n\n";
                    if ($aid > 0) {
                        $a->updateArticle($text, "", true, false, false, '', true);
                    } else {
                        $a->insertNewArticle($text, "", true, false, true, false, false);
                    }
                    // MARK CHANGES PATROLLED
                    //
                    //
                    $res = $dbr->select('recentchanges', 'max(rc_id) as rc_id', array('rc_title=\'' . mysql_real_escape_string($utitem) . '\'', 'rc_user='******'rc_cur_id=' . $aid, 'rc_patrolled=0'));
                    while ($row = $dbr->fetchObject($res)) {
                        wfDebug("UTT: mark patroll rcid: " . $row->rc_id . " \n");
                        RecentChange::markPatrolled($row->rc_id);
                        PatrolLog::record($row->rc_id, false);
                    }
                    $dbr->freeResult($res);
                    wfDebug("UTT: done\n");
                    wfDebug("UTT: Completed posting for [" . $utitem . "]\n");
                    $wgOut->addHTML("Completed posting for - " . $utitem);
                } else {
                    wfDebug("UTT: No user\n");
                    $wgOut->addHTML("UT_MSG ERROR: No user specified. \n");
                }
            } else {
                wfDebug("UTT: No message to post\n");
                $wgOut->addHTML("UT_MSG ERROR: No message to post for - " . $utitem . "\n");
                return;
            }
            $wgOut->redirect('');
        } else {
            $sk = $wgUser->getSkin();
            $wgOut->addHTML('
<script language="javascript" src="/extensions/wikihow/common/prototype1.8.2/prototype.js"></script>
<script language="javascript" src="/extensions/wikihow/common/prototype1.8.2/effects.js"></script>
<script language="javascript" src="/extensions/wikihow/common/prototype1.8.2/controls.js"></script>
		' . "\n");
            $wgOut->addHTML("\n\t\t\t<script type='text/javascript'>\n\t\t\t\tfunction utSend () {\n\n\t\t\t\t\t\$('formdiv').style.display = 'none';\n\t\t\t\t\t\$('resultdiv').innerHTML = 'Sending...<br />';\n\n\t\t\t\t\tliArray = document.getElementById('ut_ol').childNodes;\n\t\t\t\t\ti=0;\n\t\t\t\t\twhile(liArray[i]){\n\t\t\t\t\t\tif (document.getElementById(liArray[i].id)) {\n\t\t\t\t\t\t\tif (liArray[i].getAttribute('id').match(/^ut_li_/)) {\n\n\t\t\t\t\t\t\t\tdocument.forms['utForm'].utuser.value = liArray[i].getAttribute('id').replace('ut_li_','');\n\t\t\t\t\t\t\t\t\$('utForm').request({\n\t\t\t\t\t\t\t\t\tasynchronous: false,\n\t\t\t\t\t\t\t\t\tonComplete: function(transport) {\n\t\t\t\t\t\t\t\t\t\t\$('resultdiv').innerHTML += transport.responseText+'<br />';\n\t\t\t\t\t\t\t\t\t\tif (transport.responseText.match(/Completed posting for - /)){\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\tvar u = transport.responseText.replace(/Completed posting for - /,'');\n\t\t\t\t\t\t\t\t\t\t\t//\$('resultdiv').innerHTML += 'UID: '+u+'<br />';\n\t\t\t\t\t\t\t\t\t\t\t\$('ut_li_'+u).innerHTML +=  '  <img src=\"/skins/WikiHow/light_green_check.png\" height=\"15\" width=\"15\" />';\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tonFailure: function(transport) {\n\t\t\t\t\t\t\t\t\t\t\$('resultdiv').innerHTML += 'Sending returned error for '+liArray[i].id+' <br />';\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t//\$('resultdiv').innerHTML += 'Sending '+liArray[i].id+'<br />';\n\t\t\t\t\t\t \t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\ti++;\n\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t</script>\n\t\t\t\n\t\t\t");
            // GET LIST OF RECIPIENTS
            //
            //
            if ($target) {
                $t = Title::newFromUrl($target);
                if ($t->getArticleId() <= 0) {
                    $wgOut->addHTML("Target not a valid article.");
                    return;
                } else {
                    $r = Revision::newFromTitle($t);
                    $text = $r->getText();
                    #$wgOut->addHTML( $text );
                    $utcount = preg_match_all('/\\[\\[User_talk:(.*?)[#\\]\\|]/', $text, $matches);
                    #print_r($matches);
                    $utlist = $matches[1];
                }
            }
            // DISPLAY COUNT OF USER TALK PAGES FOUND
            //
            //
            if (count($utlist) == 0) {
                $wgOut->addHTML(wfMsg('notalkpagesfound'));
                return;
            } else {
                $wgOut->addHTML(count($utlist) . ' ' . wfMsg('talkpagesfound') . "<br />");
            }
            // TEXTAREA and FORM
            //
            //
            $wgOut->addHTML('
<form id="utForm" method="post">
				');
            // DISPLAY LIST OF USER TALK PAGES
            //
            //
            $wgOut->addHTML('<div id="utlist" style="border: 1px grey solid;margin: 15px 0px 15px 0px;padding: 15px;height:215px;overflow:auto"><ol id="ut_ol">' . "\n");
            foreach ($utlist as $utitem) {
                $wgOut->addHTML('<li id="ut_li_' . preg_replace('/\\s/m', '-', $utitem) . '"><a href="/User_talk:' . $utitem . '">' . $utitem . '</a></li>' . "\n");
            }
            $wgOut->addHTML('</ol></div>' . "\n");
            // TEXTAREA and FORM
            //
            //
            $wgOut->addHTML('
<div id="formdiv">
' . wfMsg('sendbox') . '<br />
<textarea id="utmessage" name="utmessage" rows="6" style="margin: 5px 0px 5px 0px;"></textarea>
<input id="utuser" type="hidden" name="utuser" value="">

<input tabindex="4" type="button" value="Send" cl1ass="btn" id="postcommentbutton" style="font-size: 110%; font-weight:bold" onclick="utSend(); return false;" />


</form>
</div>
<div id="resultdiv"></div>' . "\n");
        }
    }
 /**
  * If a user is nabbing an article, there are Skip/Cancel and Mark as
  * Patrolled buttons at the buttom of the list of NAB actions.  When
  * either of these buttons are pushed, this function processes the
  * submitted form.
  */
 private function doNABAction(&$dbw)
 {
     global $wgRequest, $wgOut, $wgUser;
     $err = false;
     $aid = $wgRequest->getVal('page', 0);
     $aid = intval($aid);
     if ($wgRequest->getVal('nap_submit', null) != null) {
         $title = Title::newFromID($aid);
         // MARK ARTICLE AS PATROLLED
         self::markNabbed($dbw, $aid, $wgUser->getId());
         if (!$title) {
             $wgOut->addHTML('Error: target page for NAB was not found');
             return;
         }
         // LOG ENTRY
         $params = array($aid);
         $log = new LogPage('nap', false);
         $log->addEntry('nap', $title, wfMsg('nap_logsummary', $title->getFullText()), $params);
         // ADD ANY TEMPLATES
         self::addTemplates($title);
         // Rising star actions FS RS
         $this->flagRisingStar($title);
         // DELETE ARTICLE IF PATROLLER WANTED THIS
         if ($wgRequest->getVal('delete', null) != null && $wgUser->isAllowed('delete')) {
             $article = new Article($title);
             $article->doDelete($wgRequest->getVal("delete_reason"));
         }
         // MOVE/RE-TITLE ARTICLE IF PATROLLER WANTED THIS
         if ($wgRequest->getVal('move', null) != null && $wgUser->isAllowed('move')) {
             if ($wgRequest->getVal('move_newtitle', null) == null) {
                 $wgOut->addHTML('Error: no target page title specified.');
                 return;
             }
             $newTarget = $wgRequest->getVal('move_newtitle');
             $newTitle = Title::newFromText($newTarget);
             if (!$newTitle) {
                 $wgOut->addHTML("Bad new title: {$newTarget}");
                 return;
             }
             $ret = $title->moveTo($newTitle);
             if (is_string($ret)) {
                 $wgOut->addHTML("Renaming of the article failed: " . wfMsg($ret));
                 $err = true;
             }
             // move the talk page if it exists
             $oldTitleTalkPage = $title->getTalkPage();
             if ($oldTitleTalkPage->exists()) {
                 $newTitleTalkPage = $newTitle->getTalkPage();
                 $err = $oldTitleTalkPage->moveTo($newTitleTalkPage) === true;
             }
             $title = $newTitle;
         }
         // MARK ALL PREVIOUS EDITS AS PATROLLED IN RC
         $maxrcid = $wgRequest->getVal('maxrcid');
         if ($maxrcid) {
             $res = $dbw->select('recentchanges', 'rc_id', array('rc_id<=' . $maxrcid, 'rc_cur_id=' . $aid, 'rc_patrolled=0'), __METHOD__);
             while ($row = $dbw->fetchObject($res)) {
                 RecentChange::markPatrolled($row->rc_id);
                 PatrolLog::record($row->rc_id, false);
             }
             $dbw->freeResult($res);
         }
         wfRunHooks("NABArticleFinished", array($aid));
     }
     // GET NEXT UNPATROLLED ARTICLE
     if ($wgRequest->getVal('nap_skip') && $wgRequest->getVal('page')) {
         // if article was skipped, clear the checkout of the
         // article, so others can NAB it
         $dbw->update('newarticlepatrol', array('nap_user_co=0'), array("nap_page", $aid), __METHOD__);
     }
     $title = $this->getNextUnpatrolledArticle($dbw, $aid);
     if (!$title) {
         $wgOut->addHTML("Unable to get next id to patrol.");
         return;
     }
     $nap = SpecialPage::getTitleFor('Newarticleboost', $title->getPrefixedText());
     $url = $nap->getFullURL() . ($this->do_newbie ? '?newbie=1' : '');
     if (!$err) {
         $wgOut->redirect($url);
     } else {
         $wgOut->addHTML("<br/><br/>Click <a href='{$nap->getFullURL()}'>here</a> to continue.");
     }
 }
 function revertTipOnArticle($pageId, $revId)
 {
     global $wgParser;
     // do not revert if no revId
     if ($revId <= 0 || $revId == null || $revId == "") {
         return false;
     }
     $undoRevision = Revision::newFromId($revId);
     $previousRevision = $undoRevision ? $undoRevision->getPrevious() : null;
     // do not revert if the page is wrong or changed..
     if (is_null($undoRevision) || is_null($previousRevision) || $undoRevision->getPage() != $previousRevision->getPage() || $undoRevision->getPage() != $pageId) {
         return false;
     }
     $title = Title::newFromID($pageId);
     $article = new Article($title);
     $undoRevisionText = $undoRevision->getText();
     $currentText = $article->getContent();
     $undoTips = Wikitext::splitTips(reset(Wikitext::getSection($undoRevisionText, "Tips", true)));
     $prevTips = Wikitext::splitTips(reset(Wikitext::getSection($previousRevision->getText(), "Tips", true)));
     $currentTipsSection = Wikitext::getSection($currentText, "Tips", true);
     $currentTips = Wikitext::splitTips($currentTipsSection[0]);
     $section = $currentTipsSection[1];
     $undoTipsFormatted = array();
     foreach ($undoTips as $tip) {
         $undoTipsFormatted[] = self::cleanTip($tip);
     }
     $prevTipsFormatted = array();
     foreach ($prevTips as $tip) {
         $prevTipsFormatted[] = self::cleanTip($tip);
     }
     $badTips = array_diff($undoTipsFormatted, $prevTipsFormatted);
     $resultTips = "== Tips ==";
     foreach ($currentTips as $currentTip) {
         $tip = self::cleanTip($currentTip);
         if (in_array($tip, $badTips)) {
             continue;
         }
         $resultTips .= "\n" . $currentTip;
     }
     $newText = $wgParser->replaceSection($currentText, $section, $resultTips);
     $success = $article->doEdit($newText, 'reverting tip from revision ' . $revId, EDIT_UPDATE | EDIT_MINOR);
     // mark the recent change as patrolled
     if ($success) {
         // should be ok to read from slave here because the change has been done earlier.
         $dbr = wfGetDB(DB_SLAVE);
         $rcid = $dbr->selectField('recentchanges', 'rc_id', array("rc_this_oldid={$revId}"));
         RecentChange::markPatrolled($rcid);
         PatrolLog::record($rcid, false);
     }
     return $success;
 }
 /**
  * Makes an entry in the database corresponding to page creation
  * Note: the title object must be loaded with the new id using resetArticleID()
  *
  * @param string $timestamp
  * @param Title $title
  * @param bool $minor
  * @param User $user
  * @param string $comment
  * @param bool $bot
  * @param string $ip
  * @param int $size
  * @param int $newId
  * @param int $patrol
  * @return RecentChange
  */
 public static function notifyNew($timestamp, &$title, $minor, &$user, $comment, $bot, $ip = '', $size = 0, $newId = 0, $patrol = 0)
 {
     $rc = new RecentChange();
     $rc->mTitle = $title;
     $rc->mPerformer = $user;
     $rc->mAttribs = array('rc_timestamp' => $timestamp, 'rc_namespace' => $title->getNamespace(), 'rc_title' => $title->getDBkey(), 'rc_type' => RC_NEW, 'rc_source' => self::SRC_NEW, 'rc_minor' => $minor ? 1 : 0, 'rc_cur_id' => $title->getArticleID(), 'rc_user' => $user->getId(), 'rc_user_text' => $user->getName(), 'rc_comment' => $comment, 'rc_this_oldid' => $newId, 'rc_last_oldid' => 0, 'rc_bot' => $bot ? 1 : 0, 'rc_ip' => self::checkIPAddress($ip), 'rc_patrolled' => intval($patrol), 'rc_new' => 1, 'rc_old_len' => 0, 'rc_new_len' => $size, 'rc_deleted' => 0, 'rc_logid' => 0, 'rc_log_type' => null, 'rc_log_action' => '', 'rc_params' => '');
     $rc->mExtra = array('prefixedDBkey' => $title->getPrefixedDBkey(), 'lastTimestamp' => 0, 'oldSize' => 0, 'newSize' => $size, 'pageStatus' => 'created');
     DeferredUpdates::addCallableUpdate(function () use($rc) {
         $rc->save();
         if ($rc->mAttribs['rc_patrolled']) {
             PatrolLog::record($rc, true, $rc->getPerformer());
         }
     });
     return $rc;
 }
 /**
  * Mark this particular edit as patrolled
  */
 function markpatrolled()
 {
     global $wgOut, $wgRequest, $wgUseRCPatrol, $wgUser;
     $wgOut->setRobotPolicy('noindex,nofollow');
     # Check RC patrol config. option
     if (!$wgUseRCPatrol) {
         $wgOut->errorPage('rcpatroldisabled', 'rcpatroldisabledtext');
         return;
     }
     # Check permissions
     if (!$wgUser->isAllowed('patrol')) {
         $wgOut->permissionRequired('patrol');
         return;
     }
     # If we haven't been given an rc_id value, we can't do anything
     $rcid = $wgRequest->getVal('rcid');
     if (!$rcid) {
         $wgOut->errorPage('markedaspatrollederror', 'markedaspatrollederrortext');
         return;
     }
     # Handle the 'MarkPatrolled' hook
     if (!wfRunHooks('MarkPatrolled', array($rcid, &$wgUser, false))) {
         return;
     }
     $return = SpecialPage::getTitleFor('Recentchanges');
     # If it's left up to us, check that the user is allowed to patrol this edit
     # If the user has the "autopatrol" right, then we'll assume there are no
     # other conditions stopping them doing so
     if (!$wgUser->isAllowed('autopatrol')) {
         $rc = RecentChange::newFromId($rcid);
         # Graceful error handling, as we've done before here...
         # (If the recent change doesn't exist, then it doesn't matter whether
         # the user is allowed to patrol it or not; nothing is going to happen
         if (is_object($rc) && $wgUser->getName() == $rc->getAttribute('rc_user_text')) {
             # The user made this edit, and can't patrol it
             # Tell them so, and then back off
             $wgOut->setPageTitle(wfMsg('markedaspatrollederror'));
             $wgOut->addWikiText(wfMsgNoTrans('markedaspatrollederror-noautopatrol'));
             $wgOut->returnToMain(false, $return);
             return;
         }
     }
     # Mark the edit as patrolled
     RecentChange::markPatrolled($rcid);
     PatrolLog::record($rcid);
     wfRunHooks('MarkPatrolledComplete', array(&$rcid, &$wgUser, false));
     # Inform the user
     $wgOut->setPageTitle(wfMsg('markedaspatrolled'));
     $wgOut->addWikiText(wfMsgNoTrans('markedaspatrolledtext'));
     $wgOut->returnToMain(false, $return);
 }
Beispiel #7
0
 /**
  * Publish the log entry.
  *
  * @param int $newId Id of the log entry.
  * @param string $to One of: rcandudp (default), rc, udp
  */
 public function publish($newId, $to = 'rcandudp')
 {
     $log = new LogPage($this->getType());
     if ($log->isRestricted()) {
         return;
     }
     $rc = $this->getRecentChange($newId);
     if ($to === 'rc' || $to === 'rcandudp') {
         $rc->save('pleasedontudp');
     }
     if ($to === 'udp' || $to === 'rcandudp') {
         $rc->notifyRCFeeds();
     }
     // Log the autopatrol if an associated rev id was passed
     if ($this->getAssociatedRevId() > 0 && $rc->getAttribute('rc_patrolled') === 1) {
         PatrolLog::record($rc, true, $this->getPerformer());
     }
 }
Beispiel #8
0
 /**
  * Generate text for a log entry
  *
  * @param $type String: log type
  * @param $action String: log action
  * @param $title Mixed: Title object or null
  * @param $skin Mixed: Skin object or null. If null, we want to use the wiki
  *              content language, since that will go to the IRC feed.
  * @param $params Array: parameters
  * @param $filterWikilinks Boolean: whether to filter wiki links
  * @return HTML string
  */
 public static function actionText($type, $action, $title = null, $skin = null, $params = array(), $filterWikilinks = false)
 {
     global $wgLang, $wgContLang, $wgLogActions;
     if (is_null($skin)) {
         $langObj = $wgContLang;
         $langObjOrNull = null;
     } else {
         $langObj = $wgLang;
         $langObjOrNull = $wgLang;
     }
     $key = "{$type}/{$action}";
     # Defer patrol log to PatrolLog class
     if ($key == 'patrol/patrol') {
         return PatrolLog::makeActionText($title, $params, $langObjOrNull);
     }
     if (isset($wgLogActions[$key])) {
         if (is_null($title)) {
             $rv = wfMsgExt($wgLogActions[$key], array('parsemag', 'escape', 'language' => $langObj));
         } else {
             $titleLink = self::getTitleLink($type, $langObjOrNull, $title, $params);
             if (preg_match('/^rights\\/(rights|autopromote)/', $key)) {
                 $rightsnone = wfMsgExt('rightsnone', array('parsemag', 'language' => $langObj));
                 if ($skin) {
                     foreach ($params as &$param) {
                         $groupArray = array_map('trim', explode(',', $param));
                         $groupArray = array_map(array('User', 'getGroupMember'), $groupArray);
                         $param = $wgLang->listToText($groupArray);
                     }
                 }
                 if (!isset($params[0]) || trim($params[0]) == '') {
                     $params[0] = $rightsnone;
                 }
                 if (!isset($params[1]) || trim($params[1]) == '') {
                     $params[1] = $rightsnone;
                 }
             }
             if (count($params) == 0) {
                 $rv = wfMsgExt($wgLogActions[$key], array('parsemag', 'escape', 'replaceafter', 'language' => $langObj), $titleLink);
             } else {
                 $details = '';
                 array_unshift($params, $titleLink);
                 // User suppression
                 if (preg_match('/^(block|suppress)\\/(block|reblock)$/', $key)) {
                     if ($skin) {
                         $params[1] = '<span class="blockExpiry" dir="ltr" title="' . htmlspecialchars($params[1]) . '">' . $wgLang->translateBlockExpiry($params[1]) . '</span>';
                     } else {
                         $params[1] = $wgContLang->translateBlockExpiry($params[1]);
                     }
                     $params[2] = isset($params[2]) ? self::formatBlockFlags($params[2], $langObj) : '';
                     // Page protections
                 } elseif ($type == 'protect' && count($params) == 3) {
                     // Restrictions and expiries
                     if ($skin) {
                         $details .= $wgLang->getDirMark() . htmlspecialchars(" {$params[1]}");
                     } else {
                         $details .= " {$params[1]}";
                     }
                     // Cascading flag...
                     if ($params[2]) {
                         $details .= ' [' . wfMsgExt('protect-summary-cascade', array('parsemag', 'language' => $langObj)) . ']';
                     }
                     // Page moves
                 } elseif ($type == 'move' && count($params) == 3) {
                     if ($params[2]) {
                         $details .= ' [' . wfMsgExt('move-redirect-suppressed', array('parsemag', 'language' => $langObj)) . ']';
                     }
                     // Revision deletion
                 } elseif (preg_match('/^(delete|suppress)\\/revision$/', $key) && count($params) == 5) {
                     $count = substr_count($params[2], ',') + 1;
                     // revisions
                     $ofield = intval(substr($params[3], 7));
                     // <ofield=x>
                     $nfield = intval(substr($params[4], 7));
                     // <nfield=x>
                     $details .= ': ' . RevisionDeleter::getLogMessage($count, $nfield, $ofield, $langObj, false);
                     // Log deletion
                 } elseif (preg_match('/^(delete|suppress)\\/event$/', $key) && count($params) == 4) {
                     $count = substr_count($params[1], ',') + 1;
                     // log items
                     $ofield = intval(substr($params[2], 7));
                     // <ofield=x>
                     $nfield = intval(substr($params[3], 7));
                     // <nfield=x>
                     $details .= ': ' . RevisionDeleter::getLogMessage($count, $nfield, $ofield, $langObj, true);
                 }
                 $rv = wfMsgExt($wgLogActions[$key], array('parsemag', 'escape', 'replaceafter', 'language' => $langObj), $params) . $details;
             }
         }
     } else {
         global $wgLogActionsHandlers;
         if (isset($wgLogActionsHandlers[$key])) {
             $args = func_get_args();
             $rv = call_user_func_array($wgLogActionsHandlers[$key], $args);
         } else {
             wfDebug("LogPage::actionText - unknown action {$key}\n");
             $rv = "{$action}";
         }
     }
     // For the perplexed, this feature was added in r7855 by Erik.
     // The feature was added because we liked adding [[$1]] in our log entries
     // but the log entries are parsed as Wikitext on RecentChanges but as HTML
     // on Special:Log. The hack is essentially that [[$1]] represented a link
     // to the title in question. The first parameter to the HTML version (Special:Log)
     // is that link in HTML form, and so this just gets rid of the ugly [[]].
     // However, this is a horrible hack and it doesn't work like you expect if, say,
     // you want to link to something OTHER than the title of the log entry.
     // The real problem, which Erik was trying to fix (and it sort-of works now) is
     // that the same messages are being treated as both wikitext *and* HTML.
     if ($filterWikilinks) {
         $rv = str_replace('[[', '', $rv);
         $rv = str_replace(']]', '', $rv);
     }
     return $rv;
 }
Beispiel #9
0
 static function markPatrolledCallback(&$article, $rcid)
 {
     global $wgRequest, $wgUser, $wgOut;
     // check if skip has been passed to us
     if ($wgRequest->getInt('skip', null) != 1) {
         // find his and lows
         $rcids = array();
         $rcids[] = $rcid;
         if ($wgRequest->getVal('rchi', null) && $wgRequest->getVal('rclow', null)) {
             $hilos = wfGetRCPatrols($rcid, $wgRequest->getVal('rchi'), $wgRequest->getVal('rclow'), $article->mTitle->getArticleID());
             $rcids = array_merge($rcids, $hilos);
         }
         $rcids = array_unique($rcids);
         foreach ($rcids as $id) {
             RecentChange::markPatrolled($id, $article);
             PatrolLog::record($id, false);
         }
         wfRunHooks('MarkPatrolledBatchComplete', array(&$article, &$rcids, &$wgUser));
         wfRunHooks('MarkPatrolledComplete', array(&$rcid, &$wgUser, false));
     } else {
         self::skipPatrolled($article);
     }
     $show_namespace = $wgRequest->getVal('show_namespace');
     $invert = $wgRequest->getVal('invert');
     $reverse = $wgRequest->getVal('reverse');
     $featured = $wgRequest->getVal('featured');
     $fromrc = $wgRequest->getVal('fromrc', null) == null ? "" : "&fromrc=1";
     //TODO: shorten this to a selectRow call
     $sql = "SELECT rc_id, rc_cur_id, rc_moved_to_ns, \n\t\t\trc_moved_to_title, rc_new, rc_namespace, rc_title, rc_last_oldid, rc_this_oldid FROM recentchanges " . ($featured ? " LEFT OUTER JOIN page on page_title = rc_title and page_namespace = rc_namespace " : "") . " WHERE rc_id " . ($reverse == 1 ? " > " : " < ") . " {$rcid} and rc_patrolled = 0  " . ($featured ? " AND page_is_featured = 1 " : "") . " AND rc_user_text != '" . $wgUser->getName() . "' ";
     if ($show_namespace != null && $show_namespace != '') {
         $sql .= " AND rc_namespace " . ($invert ? '!=' : '=') . $show_namespace;
     } else {
         // avoid the delete logs, etc
         $sql .= " AND rc_namespace NOT IN ( " . NS_VIDEO . ") ";
     }
     $sql .= " ORDER by rc_id " . ($reverse == 1 ? " ASC " : " DESC ") . "  LIMIT 1";
     $dbw = wfGetDB(DB_MASTER);
     $res = $dbw->query($sql);
     if ($row = $dbw->fetchObject($res)) {
         $xx = Title::makeTitle($row->rc_namespace, $row->rc_title);
         if ($row->rc_moved_to_title != "") {
             $xx = Title::makeTitle($row->rc_moved_to_ns, $row->rc_moved_to_title);
         }
         $url = "";
         if ($row->rc_new == 1) {
             $url = $xx->getFullURL() . "?redirect=no&rcid=" . $row->rc_id;
         } else {
             $url = $xx->getFullURL() . "?title=" . $xx->getPrefixedURL() . "&curid=" . $row->rc_cur_id . "&diff={$row->rc_this_oldid}&oldid=" . $row->rc_last_oldid . "&rcid=" . $row->rc_id;
         }
         if ($show_namespace != null) {
             $url .= "&show_namespace={$show_namespace}&invert={$invert}";
         }
         $url .= "&reverse={$reverse}&featured={$featured}{$fromrc}";
         $dbw->freeResult($res);
         $wgOut->redirect($url);
         return false;
     }
     return true;
 }
Beispiel #10
0
 function execute($par)
 {
     global $wgRequest, $wgOut, $wgUser;
     $target = isset($par) ? $par : $wgRequest->getVal('target');
     if ($target == $wgUser->getName()) {
         $wgOut->addHTML(wfMsg('bunchpatrol_noselfpatrol'));
         return;
     }
     $wgOut->setHTMLTitle('Bunch Patrol - wikiHow');
     $sk = $wgUser->getSkin();
     $dbr =& wfGetDB(DB_SLAVE);
     $me = Title::makeTitle(NS_SPECIAL, "Bunchpatrol");
     $unpatrolled = $dbr->selectField('recentchanges', array('count(*)'), array('rc_patrolled=0'));
     if (!strlen($target)) {
         $restrict = " AND (rc_namespace = 2 OR rc_namespace = 3) ";
         $res = $dbr->query("SELECT rc_user, rc_user_text, COUNT(*) AS C\n\t\t\t\t\t\t\t\tFROM recentchanges\n\t\t\t\t\t\t\t\tWHERE rc_patrolled=0\n\t\t\t\t\t\t\t\t\t{$restrict}\n\t\t\t\t\t\t\t\tGROUP BY rc_user_text HAVING C > 2\n\t\t\t\t\t\t\t\tORDER BY C DESC");
         $wgOut->addHTML("<table width='85%' align='center'>");
         while (($row = $dbr->fetchObject($res)) != null) {
             $u = User::newFromName($row->rc_user_text);
             if ($u) {
                 $bpLink = SpecialPage::getTitleFor('Bunchpatrol', $u->getName());
                 $wgOut->addHTML("<tr><td>" . $sk->makeLinkObj($bpLink, $u->getName()) . "</td><td>{$row->C}</td>");
             }
         }
         $dbr->freeResult($res);
         $wgOut->addHTML("</table>");
         return;
     }
     if ($wgRequest->wasPosted() && $wgUser->isAllowed('patrol')) {
         $values = $wgRequest->getValues();
         $vals = array();
         foreach ($values as $key => $value) {
             if (strpos($key, "rc_") === 0 && $value == 'on') {
                 $vals[] = str_replace("rc_", "", $key);
             }
         }
         foreach ($vals as $val) {
             RecentChange::markPatrolled($val);
             PatrolLog::record($val, false);
         }
         $restrict = " AND (rc_namespace = 2 OR rc_namespace = 3) ";
         $res = $dbr->query("SELECT rc_user, rc_user_text, COUNT(*) AS C\n\t\t\t\t\t\t\t\tFROM recentchanges\n\t\t\t\t\t\t\t\tWHERE rc_patrolled=0\n\t\t\t\t\t\t\t\t\t{$restrict}\n\t\t\t\t\t\t\t\tGROUP BY rc_user_text HAVING C > 2\n\t\t\t\t\t\t\t\tORDER BY C DESC");
         $wgOut->addHTML("<table width='85%' align='center'>");
         while (($row = $dbr->fetchObject($res)) != null) {
             $u = User::newFromName($row->rc_user_text);
             if ($u) {
                 $wgOut->addHTML("<tr><td>" . $sk->makeLinkObj($me, $u->getName(), "target=" . $u->getName()) . "</td><td>{$row->C}</td>");
             }
         }
         $wgOut->addHTML("</table>");
         return;
     }
     // don't show main namespace edits if there are < 500 total unpatrolled edits
     $target = str_replace('-', ' ', $target);
     $wgOut->addHTML("\n\t\t\t<script type='text/javascript'>\n\t\t\tfunction checkall(selected) {\n\t\t\t\tfor (i = 0; i < document.checkform.elements.length; i++) {\n\t\t\t\t\tvar e = document.checkform.elements[i];\n\t\t\t\t\tif (e.type=='checkbox') {\n\t\t\t\t\t\te.checked = selected;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t</script>\n\t\t\t<form method='POST' name='checkform' action='{$me->getFullURL()}'>\n\t\t\t<input type='hidden' name='target' value='{$target}'>\n\t\t\t");
     if ($wgUser->isSysop()) {
         $wgOut->addHTML("Select: <input type='button' onclick='checkall(true);' value='All'/>\n\t\t\t\t\t<input type='button' onclick='checkall(false);' value='None'/>\n\t\t\t\t");
     }
     $count = $this->writeBunchPatrolTableContent($dbr, $target, false);
     if ($count > 0) {
         $wgOut->addHTML("<input type='submit' value='" . wfMsg('submit') . "'>");
     }
     $wgOut->addHTML("</form>");
     $wgOut->setPageTitle(wfMsg('bunchpatrol'));
     if ($count == 0) {
         $wgOut->addWikiText(wfMsg('bunchpatrol_nounpatrollededits', $target));
     }
 }
Beispiel #11
0
 /**
  * Article::doEdit()
  *
  * Change an existing article or create a new article. Updates RC and all necessary caches,
  * optionally via the deferred update array.
  *
  * $wgUser must be set before calling this function.
  *
  * @param string $text New text
  * @param string $summary Edit summary
  * @param integer $flags bitfield:
  *	  EDIT_NEW
  *		  Article is known or assumed to be non-existent, create a new one
  *	  EDIT_UPDATE
  *		  Article is known or assumed to be pre-existing, update it
  *	  EDIT_MINOR
  *		  Mark this edit minor, if the user is allowed to do so
  *	  EDIT_SUPPRESS_RC
  *		  Do not log the change in recentchanges
  *	  EDIT_FORCE_BOT
  *		  Mark the edit a "bot" edit regardless of user rights
  *	  EDIT_DEFER_UPDATES
  *		  Defer some of the updates until the end of index.php
  *	  EDIT_AUTOSUMMARY
  *		  Fill in blank summaries with generated text where possible
  *
  * If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the article will be detected.
  * If EDIT_UPDATE is specified and the article doesn't exist, the function will return false. If
  * EDIT_NEW is specified and the article does exist, a duplicate key error will cause an exception
  * to be thrown from the Database. These two conditions are also possible with auto-detection due
  * to MediaWiki's performance-optimised locking strategy.
  *
  * @return bool success
  */
 function doEdit($text, $summary, $flags = 0)
 {
     global $wgUser, $wgDBtransactions, $wgIgnoreNamespacesForEditCount;
     #echo wfBacktrace(); exit;
     wfProfileIn(__METHOD__);
     $good = true;
     if (!($flags & EDIT_NEW) && !($flags & EDIT_UPDATE)) {
         $aid = $this->mTitle->getArticleID(GAID_FOR_UPDATE);
         if ($aid) {
             $flags |= EDIT_UPDATE;
         } else {
             $flags |= EDIT_NEW;
         }
     }
     if (!wfRunHooks('ArticleSave', array(&$this, &$wgUser, &$text, &$summary, $flags & EDIT_MINOR, null, null, &$flags))) {
         wfDebug(__METHOD__ . ": ArticleSave hook aborted save!\n");
         wfProfileOut(__METHOD__);
         return false;
     }
     # Silently ignore EDIT_MINOR if not allowed
     $isminor = $flags & EDIT_MINOR && $wgUser->isAllowed('minoredit');
     $bot = $flags & EDIT_FORCE_BOT;
     $oldtext = $this->getContent();
     $oldsize = strlen($oldtext);
     # Provide autosummaries if one is not provided.
     if ($flags & EDIT_AUTOSUMMARY && $summary == '') {
         $summary = $this->getAutosummary($oldtext, $text, $flags);
     }
     $editInfo = $this->prepareTextForEdit($text);
     $text = $editInfo->pst;
     $newsize = strlen($text);
     $dbw = wfGetDB(DB_MASTER);
     $now = wfTimestampNow();
     if ($flags & EDIT_UPDATE) {
         # Update article, but only if changed.
         # Make sure the revision is either completely inserted or not inserted at all
         if (!$wgDBtransactions) {
             $userAbort = ignore_user_abort(true);
         }
         $lastRevision = 0;
         $revisionId = 0;
         $changed = strcmp($text, $oldtext) != 0;
         if ($changed) {
             $this->mGoodAdjustment = (int) $this->isCountable($text) - (int) $this->isCountable($oldtext);
             $this->mTotalAdjustment = 0;
             $lastRevision = $dbw->selectField('page', 'page_latest', array('page_id' => $this->getId()));
             if (!$lastRevision) {
                 # Article gone missing
                 wfDebug(__METHOD__ . ": EDIT_UPDATE specified but article doesn't exist\n");
                 wfProfileOut(__METHOD__);
                 return false;
             }
             $revision = new Revision(array('page' => $this->getId(), 'comment' => $summary, 'minor_edit' => $isminor, 'text' => $text));
             $dbw->begin();
             $revisionId = $revision->insertOn($dbw);
             # Update page
             $ok = $this->updateRevisionOn($dbw, $revision, $lastRevision);
             if (!$ok) {
                 /* Belated edit conflict! Run away!! */
                 $good = false;
                 $dbw->rollback();
             } else {
                 # Update recentchanges
                 if (!($flags & EDIT_SUPPRESS_RC)) {
                     $rcid = RecentChange::notifyEdit($now, $this->mTitle, $isminor, $wgUser, $summary, $lastRevision, $this->getTimestamp(), $bot, '', $oldsize, $newsize, $revisionId);
                     # Mark as patrolled if the user can do so
                     if ($GLOBALS['wgUseRCPatrol'] && $wgUser->isAllowed('autopatrol') && $wgUser->getOption('autopatrol') || in_array("bot", $wgUser->getGroups())) {
                         RecentChange::markPatrolled($rcid, $this);
                         PatrolLog::record($rcid, true);
                     }
                 }
                 //XXCHANGED - we ignore some namespace edits
                 if (!in_array($this->mTitle->getNamespace(), $wgIgnoreNamespacesForEditCount)) {
                     $wgUser->incEditCount();
                 }
                 $dbw->commit();
             }
         } else {
             $revision = null;
             // Keep the same revision ID, but do some updates on it
             $revisionId = $this->getRevIdFetched();
             // Update page_touched, this is usually implicit in the page update
             // Other cache updates are done in onArticleEdit()
             $this->mTitle->invalidateCache();
         }
         if (!$wgDBtransactions) {
             ignore_user_abort($userAbort);
         }
         if ($good) {
             # Invalidate cache of this article and all pages using this article
             # as a template. Partly deferred.
             Article::onArticleEdit($this->mTitle);
             # Update links tables, site stats, etc.
             $this->editUpdates($text, $summary, $isminor, $now, $revisionId, $changed);
         }
     } else {
         # Create new article
         # Set statistics members
         # We work out if it's countable after PST to avoid counter drift
         # when articles are created with {{subst:}}
         $this->mGoodAdjustment = (int) $this->isCountable($text);
         $this->mTotalAdjustment = 1;
         $dbw->begin();
         # Add the page record; stake our claim on this title!
         # This will fail with a database query exception if the article already exists
         $newid = $this->insertOn($dbw);
         # Save the revision text...
         $revision = new Revision(array('page' => $newid, 'comment' => $summary, 'minor_edit' => $isminor, 'text' => $text));
         $revisionId = $revision->insertOn($dbw);
         $this->mTitle->resetArticleID($newid);
         # Update the page record with revision data
         $this->updateRevisionOn($dbw, $revision, 0);
         if (!($flags & EDIT_SUPPRESS_RC)) {
             $rcid = RecentChange::notifyNew($now, $this->mTitle, $isminor, $wgUser, $summary, $bot, '', strlen($text), $revisionId);
             # Mark as patrolled if the user can
             if (($GLOBALS['wgUseRCPatrol'] || $GLOBALS['wgUseNPPatrol']) && $wgUser->isAllowed('autopatrol') && $wgUser->getOption('autopatrol') || in_array("bot", $wgUser->getGroups())) {
                 RecentChange::markPatrolled($rcid, $this);
                 PatrolLog::record($rcid, true);
             }
         }
         //XXCHANGED - we ignore some namespace edits
         if (!in_array($this->mTitle->getNamespace(), $wgIgnoreNamespacesForEditCount)) {
             $wgUser->incEditCount();
         }
         $dbw->commit();
         # Update links, etc.
         $this->editUpdates($text, $summary, $isminor, $now, $revisionId, true);
         # Clear caches
         Article::onArticleCreate($this->mTitle);
         wfRunHooks('ArticleInsertComplete', array(&$this, &$wgUser, $text, $summary, $flags & EDIT_MINOR, null, null, &$flags, $revision));
     }
     if ($good && !($flags & EDIT_DEFER_UPDATES)) {
         wfDoUpdates();
     }
     if ($good) {
         wfRunHooks('ArticleSaveComplete', array(&$this, &$wgUser, $text, $summary, $flags & EDIT_MINOR, null, null, &$flags, $revision));
     }
     wfProfileOut(__METHOD__);
     return $good;
 }
 /**
  * @static
  */
 static function actionText($type, $action, $title = NULL, $skin = NULL, $params = array(), $filterWikilinks = false)
 {
     global $wgLang, $wgContLang, $wgLogActions;
     $key = "{$type}/{$action}";
     if ($key == 'patrol/patrol') {
         return PatrolLog::makeActionText($title, $params, $skin);
     }
     if (isset($wgLogActions[$key])) {
         if (is_null($title)) {
             $rv = wfMsg($wgLogActions[$key]);
         } else {
             if ($skin) {
                 switch ($type) {
                     case 'move':
                         $titleLink = $skin->makeLinkObj($title, $title->getPrefixedText(), 'redirect=no');
                         $params[0] = $skin->makeLinkObj(Title::newFromText($params[0]), htmlspecialchars($params[0]));
                         break;
                     case 'block':
                         if (substr($title->getText(), 0, 1) == '#') {
                             $titleLink = $title->getText();
                         } else {
                             // TODO: Store the user identifier in the parameters
                             // to make this faster for future log entries
                             $id = User::idFromName($title->getText());
                             $titleLink = $skin->userLink($id, $title->getText()) . $skin->userToolLinks($id, $title->getText(), false, Linker::TOOL_LINKS_NOBLOCK);
                         }
                         break;
                     case 'rights':
                         $text = $wgContLang->ucfirst($title->getText());
                         $titleLink = $skin->makeLinkObj(Title::makeTitle(NS_USER, $text));
                         break;
                     case 'merge':
                         $titleLink = $skin->makeLinkObj($title, $title->getPrefixedText(), 'redirect=no');
                         $params[0] = $skin->makeLinkObj(Title::newFromText($params[0]), htmlspecialchars($params[0]));
                         $params[1] = $wgLang->timeanddate($params[1]);
                         break;
                     default:
                         $titleLink = $skin->makeLinkObj($title);
                 }
             } else {
                 $titleLink = $title->getPrefixedText();
             }
             if ($key == 'rights/rights') {
                 if ($skin) {
                     $rightsnone = wfMsg('rightsnone');
                 } else {
                     $rightsnone = wfMsgForContent('rightsnone');
                 }
                 if (!isset($params[0]) || trim($params[0]) == '') {
                     $params[0] = $rightsnone;
                 }
                 if (!isset($params[1]) || trim($params[1]) == '') {
                     $params[1] = $rightsnone;
                 }
             }
             if (count($params) == 0) {
                 if ($skin) {
                     $rv = wfMsg($wgLogActions[$key], $titleLink);
                 } else {
                     $rv = wfMsgForContent($wgLogActions[$key], $titleLink);
                 }
             } else {
                 array_unshift($params, $titleLink);
                 if ($key == 'block/block') {
                     if ($skin) {
                         $params[1] = '<span title="' . htmlspecialchars($params[1]) . '">' . $wgLang->translateBlockExpiry($params[1]) . '</span>';
                     } else {
                         $params[1] = $wgContLang->translateBlockExpiry($params[1]);
                     }
                     $params[2] = isset($params[2]) ? self::formatBlockFlags($params[2]) : '';
                 }
                 $rv = wfMsgReal($wgLogActions[$key], $params, true, !$skin);
             }
         }
     } else {
         wfDebug("LogPage::actionText - unknown action {$key}\n");
         $rv = "{$action}";
     }
     if ($filterWikilinks) {
         $rv = str_replace("[[", "", $rv);
         $rv = str_replace("]]", "", $rv);
     }
     return $rv;
 }
 /**
  * Mark this particular edit/page as patrolled
  */
 function markpatrolled()
 {
     global $wgOut, $wgRequest, $wgUseRCPatrol, $wgUseNPPatrol, $wgUser;
     $wgOut->setRobotPolicy('noindex,nofollow');
     # Check patrol config options
     if (!($wgUseNPPatrol || $wgUseRCPatrol)) {
         $wgOut->errorPage('rcpatroldisabled', 'rcpatroldisabledtext');
         return;
     }
     # If we haven't been given an rc_id value, we can't do anything
     $rcid = (int) $wgRequest->getVal('rcid');
     $rc = $rcid ? RecentChange::newFromId($rcid) : null;
     if (is_null($rc)) {
         $wgOut->errorPage('markedaspatrollederror', 'markedaspatrollederrortext');
         return;
     }
     if (!$wgUseRCPatrol && $rc->mAttribs['rc_type'] != RC_NEW) {
         // Only new pages can be patrolled if the general patrolling is off....???
         // @fixme -- is this necessary? Shouldn't we only bother controlling the
         // front end here?
         $wgOut->errorPage('rcpatroldisabled', 'rcpatroldisabledtext');
         return;
     }
     # Check permissions
     $permission_errors = $this->mTitle->getUserPermissionsErrors('patrol', $wgUser);
     if (count($permission_errors) > 0) {
         $wgOut->showPermissionsErrorPage($permission_errors);
         return;
     }
     # Handle the 'MarkPatrolled' hook
     if (!wfRunHooks('MarkPatrolled', array($rcid, &$wgUser, false))) {
         return;
     }
     #It would be nice to see where the user had actually come from, but for now just guess
     $returnto = $rc->mAttribs['rc_type'] == RC_NEW ? 'Newpages' : 'Recentchanges';
     $return = Title::makeTitle(NS_SPECIAL, $returnto);
     # If it's left up to us, check that the user is allowed to patrol this edit
     # If the user has the "autopatrol" right, then we'll assume there are no
     # other conditions stopping them doing so
     if (!$wgUser->isAllowed('autopatrol')) {
         $rc = RecentChange::newFromId($rcid);
         # Graceful error handling, as we've done before here...
         # (If the recent change doesn't exist, then it doesn't matter whether
         # the user is allowed to patrol it or not; nothing is going to happen
         if (is_object($rc) && $wgUser->getName() == $rc->getAttribute('rc_user_text')) {
             # The user made this edit, and can't patrol it
             # Tell them so, and then back off
             $wgOut->setPageTitle(wfMsg('markedaspatrollederror'));
             $wgOut->addWikiMsg('markedaspatrollederror-noautopatrol');
             $wgOut->returnToMain(false, $return);
             return;
         }
     }
     # Mark the edit as patrolled
     RecentChange::markPatrolled($rcid);
     PatrolLog::record($rcid);
     wfRunHooks('MarkPatrolledComplete', array(&$rcid, &$wgUser, false));
     # Inform the user
     $wgOut->setPageTitle(wfMsg('markedaspatrolled'));
     $wgOut->addWikiMsg('markedaspatrolledtext');
     $wgOut->returnToMain(false, $return);
 }
Beispiel #14
0
 /**
  * @static
  * @return HTML string
  */
 static function actionText($type, $action, $title = NULL, $skin = NULL, $params = array(), $filterWikilinks = false)
 {
     global $wgLang, $wgContLang, $wgLogActions, $wgMessageCache;
     $wgMessageCache->loadAllMessages();
     $key = "{$type}/{$action}";
     # Defer patrol log to PatrolLog class
     if ($key == 'patrol/patrol') {
         return PatrolLog::makeActionText($title, $params, $skin);
     }
     if (isset($wgLogActions[$key])) {
         if (is_null($title)) {
             $rv = wfMsg($wgLogActions[$key]);
         } else {
             $titleLink = self::getTitleLink($type, $skin, $title, $params);
             if ($key == 'rights/rights') {
                 if ($skin) {
                     $rightsnone = wfMsg('rightsnone');
                     foreach ($params as &$param) {
                         $groupArray = array_map('trim', explode(',', $param));
                         $groupArray = array_map(array('User', 'getGroupName'), $groupArray);
                         $param = $wgLang->listToText($groupArray);
                     }
                 } else {
                     $rightsnone = wfMsgForContent('rightsnone');
                 }
                 if (!isset($params[0]) || trim($params[0]) == '') {
                     $params[0] = $rightsnone;
                 }
                 if (!isset($params[1]) || trim($params[1]) == '') {
                     $params[1] = $rightsnone;
                 }
             }
             if (count($params) == 0) {
                 if ($skin) {
                     $rv = wfMsg($wgLogActions[$key], $titleLink);
                 } else {
                     $rv = wfMsgForContent($wgLogActions[$key], $titleLink);
                 }
             } else {
                 $details = '';
                 array_unshift($params, $titleLink);
                 if ($key == 'block/block' || $key == 'suppress/block' || $key == 'block/reblock') {
                     if ($skin) {
                         $params[1] = '<span title="' . htmlspecialchars($params[1]) . '">' . $wgLang->translateBlockExpiry($params[1]) . '</span>';
                     } else {
                         $params[1] = $wgContLang->translateBlockExpiry($params[1]);
                     }
                     $params[2] = isset($params[2]) ? self::formatBlockFlags($params[2], is_null($skin)) : '';
                 } else {
                     if ($type == 'protect' && count($params) == 3) {
                         $details .= " {$params[1]}";
                         // restrictions and expiries
                         if ($params[2]) {
                             $details .= ' [' . wfMsg('protect-summary-cascade') . ']';
                         }
                     } else {
                         if ($type == 'move' && count($params) == 3) {
                             if ($params[2]) {
                                 $details .= ' [' . wfMsg('move-redirect-suppressed') . ']';
                             }
                         }
                     }
                 }
                 $rv = wfMsgReal($wgLogActions[$key], $params, true, !$skin) . $details;
             }
         }
     } else {
         global $wgLogActionsHandlers;
         if (isset($wgLogActionsHandlers[$key])) {
             $args = func_get_args();
             $rv = call_user_func_array($wgLogActionsHandlers[$key], $args);
         } else {
             wfDebug("LogPage::actionText - unknown action {$key}\n");
             $rv = "{$action}";
         }
     }
     if ($filterWikilinks) {
         $rv = str_replace("[[", "", $rv);
         $rv = str_replace("]]", "", $rv);
     }
     return $rv;
 }
Beispiel #15
0
 /**
  * Publish the log entry.
  *
  * @param int $newId Id of the log entry.
  * @param string $to One of: rcandudp (default), rc, udp
  */
 public function publish($newId, $to = 'rcandudp')
 {
     DeferredUpdates::addCallableUpdate(function () use($newId, $to) {
         $log = new LogPage($this->getType());
         if (!$log->isRestricted()) {
             $rc = $this->getRecentChange($newId);
             if ($to === 'rc' || $to === 'rcandudp') {
                 // save RC, passing tags so they are applied there
                 $tags = $this->getTags();
                 if (is_null($tags)) {
                     $tags = [];
                 }
                 $rc->addTags($tags);
                 $rc->save('pleasedontudp');
             }
             if ($to === 'udp' || $to === 'rcandudp') {
                 $rc->notifyRCFeeds();
             }
             // Log the autopatrol if the log entry is patrollable
             if ($this->getIsPatrollable() && $rc->getAttribute('rc_patrolled') === 1) {
                 PatrolLog::record($rc, true, $this->getPerformer());
             }
         }
     }, DeferredUpdates::POSTSEND, wfGetDB(DB_MASTER));
 }
Beispiel #16
0
 /**
  * Article::doEdit()
  *
  * Change an existing article or create a new article. Updates RC and all necessary caches,
  * optionally via the deferred update array.
  *
  * $wgUser must be set before calling this function.
  *
  * @param $text String: new text
  * @param $summary String: edit summary
  * @param $flags Integer bitfield:
  *      EDIT_NEW
  *          Article is known or assumed to be non-existent, create a new one
  *      EDIT_UPDATE
  *          Article is known or assumed to be pre-existing, update it
  *      EDIT_MINOR
  *          Mark this edit minor, if the user is allowed to do so
  *      EDIT_SUPPRESS_RC
  *          Do not log the change in recentchanges
  *      EDIT_FORCE_BOT
  *          Mark the edit a "bot" edit regardless of user rights
  *      EDIT_DEFER_UPDATES
  *          Defer some of the updates until the end of index.php
  *      EDIT_AUTOSUMMARY
  *          Fill in blank summaries with generated text where possible
  *
  * If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the article will be detected.
  * If EDIT_UPDATE is specified and the article doesn't exist, the function will an
  * edit-gone-missing error. If EDIT_NEW is specified and the article does exist, an
  * edit-already-exists error will be returned. These two conditions are also possible with
  * auto-detection due to MediaWiki's performance-optimised locking strategy.
  *
  * @param $baseRevId the revision ID this edit was based off, if any
  * @param $user Optional user object, $wgUser will be used if not passed
  *
  * @return Status object. Possible errors:
  *     edit-hook-aborted:       The ArticleSave hook aborted the edit but didn't set the fatal flag of $status
  *     edit-gone-missing:       In update mode, but the article didn't exist
  *     edit-conflict:           In update mode, the article changed unexpectedly
  *     edit-no-change:          Warning that the text was the same as before
  *     edit-already-exists:     In creation mode, but the article already exists
  *
  *  Extensions may define additional errors.
  *
  *  $return->value will contain an associative array with members as follows:
  *     new:                     Boolean indicating if the function attempted to create a new article
  *     revision:                The revision object for the inserted revision, or null
  *
  *  Compatibility note: this function previously returned a boolean value indicating success/failure
  */
 public function doEdit($text, $summary, $flags = 0, $baseRevId = false, $user = null)
 {
     global $wgUser, $wgDBtransactions, $wgUseAutomaticEditSummaries;
     # Low-level sanity check
     if ($this->mTitle->getText() === '') {
         throw new MWException('Something is trying to edit an article with an empty title');
     }
     wfProfileIn(__METHOD__);
     $user = is_null($user) ? $wgUser : $user;
     $status = Status::newGood(array());
     # Load $this->mTitle->getArticleID() and $this->mLatest if it's not already
     $this->loadPageData();
     $flags = $this->checkFlags($flags);
     if (!wfRunHooks('ArticleSave', array(&$this, &$user, &$text, &$summary, $flags & EDIT_MINOR, null, null, &$flags, &$status))) {
         wfDebug(__METHOD__ . ": ArticleSave hook aborted save!\n");
         if ($status->isOK()) {
             $status->fatal('edit-hook-aborted');
         }
         wfProfileOut(__METHOD__);
         return $status;
     }
     # Silently ignore EDIT_MINOR if not allowed
     $isminor = $flags & EDIT_MINOR && $user->isAllowed('minoredit');
     $bot = $flags & EDIT_FORCE_BOT;
     $oldtext = $this->getRawText();
     // current revision
     $oldsize = strlen($oldtext);
     # Provide autosummaries if one is not provided and autosummaries are enabled.
     if ($wgUseAutomaticEditSummaries && $flags & EDIT_AUTOSUMMARY && $summary == '') {
         $summary = $this->getAutosummary($oldtext, $text, $flags);
     }
     $editInfo = $this->prepareTextForEdit($text);
     $text = $editInfo->pst;
     $newsize = strlen($text);
     $dbw = wfGetDB(DB_MASTER);
     $now = wfTimestampNow();
     $this->mTimestamp = $now;
     if ($flags & EDIT_UPDATE) {
         # Update article, but only if changed.
         $status->value['new'] = false;
         # Make sure the revision is either completely inserted or not inserted at all
         if (!$wgDBtransactions) {
             $userAbort = ignore_user_abort(true);
         }
         $changed = strcmp($text, $oldtext) != 0;
         if ($changed) {
             $this->mGoodAdjustment = (int) $this->isCountable($text) - (int) $this->isCountable($oldtext);
             $this->mTotalAdjustment = 0;
             if (!$this->mLatest) {
                 # Article gone missing
                 wfDebug(__METHOD__ . ": EDIT_UPDATE specified but article doesn't exist\n");
                 $status->fatal('edit-gone-missing');
                 wfProfileOut(__METHOD__);
                 return $status;
             }
             $revision = new Revision(array('page' => $this->getId(), 'comment' => $summary, 'minor_edit' => $isminor, 'text' => $text, 'parent_id' => $this->mLatest, 'user' => $user->getId(), 'user_text' => $user->getName()));
             $dbw->begin();
             $revisionId = $revision->insertOn($dbw);
             # Update page
             #
             # Note that we use $this->mLatest instead of fetching a value from the master DB
             # during the course of this function. This makes sure that EditPage can detect
             # edit conflicts reliably, either by $ok here, or by $article->getTimestamp()
             # before this function is called. A previous function used a separate query, this
             # creates a window where concurrent edits can cause an ignored edit conflict.
             $ok = $this->updateRevisionOn($dbw, $revision, $this->mLatest);
             if (!$ok) {
                 /* Belated edit conflict! Run away!! */
                 $status->fatal('edit-conflict');
                 # Delete the invalid revision if the DB is not transactional
                 if (!$wgDBtransactions) {
                     $dbw->delete('revision', array('rev_id' => $revisionId), __METHOD__);
                 }
                 $revisionId = 0;
                 $dbw->rollback();
             } else {
                 global $wgUseRCPatrol;
                 wfRunHooks('NewRevisionFromEditComplete', array($this, $revision, $baseRevId, $user));
                 # Update recentchanges
                 if (!($flags & EDIT_SUPPRESS_RC)) {
                     # Mark as patrolled if the user can do so
                     $patrolled = $wgUseRCPatrol && $this->mTitle->userCan('autopatrol');
                     # Add RC row to the DB
                     $rc = RecentChange::notifyEdit($now, $this->mTitle, $isminor, $user, $summary, $this->mLatest, $this->getTimestamp(), $bot, '', $oldsize, $newsize, $revisionId, $patrolled);
                     # Log auto-patrolled edits
                     if ($patrolled) {
                         PatrolLog::record($rc, true);
                     }
                 }
                 $user->incEditCount();
                 $dbw->commit();
             }
         } else {
             $status->warning('edit-no-change');
             $revision = null;
             // Keep the same revision ID, but do some updates on it
             $revisionId = $this->getRevIdFetched();
             // Update page_touched, this is usually implicit in the page update
             // Other cache updates are done in onArticleEdit()
             $this->mTitle->invalidateCache();
         }
         if (!$wgDBtransactions) {
             ignore_user_abort($userAbort);
         }
         // Now that ignore_user_abort is restored, we can respond to fatal errors
         if (!$status->isOK()) {
             wfProfileOut(__METHOD__);
             return $status;
         }
         # Invalidate cache of this article and all pages using this article
         # as a template. Partly deferred.
         Article::onArticleEdit($this->mTitle);
         # Update links tables, site stats, etc.
         $this->editUpdates($text, $summary, $isminor, $now, $revisionId, $changed);
     } else {
         # Create new article
         $status->value['new'] = true;
         # Set statistics members
         # We work out if it's countable after PST to avoid counter drift
         # when articles are created with {{subst:}}
         $this->mGoodAdjustment = (int) $this->isCountable($text);
         $this->mTotalAdjustment = 1;
         $dbw->begin();
         # Add the page record; stake our claim on this title!
         # This will return false if the article already exists
         $newid = $this->insertOn($dbw);
         if ($newid === false) {
             $dbw->rollback();
             $status->fatal('edit-already-exists');
             wfProfileOut(__METHOD__);
             return $status;
         }
         # Save the revision text...
         $revision = new Revision(array('page' => $newid, 'comment' => $summary, 'minor_edit' => $isminor, 'text' => $text, 'user' => $user->getId(), 'user_text' => $user->getName()));
         $revisionId = $revision->insertOn($dbw);
         $this->mTitle->resetArticleID($newid);
         # Update the page record with revision data
         $this->updateRevisionOn($dbw, $revision, 0);
         wfRunHooks('NewRevisionFromEditComplete', array($this, $revision, false, $user));
         # Update recentchanges
         if (!($flags & EDIT_SUPPRESS_RC)) {
             global $wgUseRCPatrol, $wgUseNPPatrol;
             # Mark as patrolled if the user can do so
             $patrolled = ($wgUseRCPatrol || $wgUseNPPatrol) && $this->mTitle->userCan('autopatrol');
             # Add RC row to the DB
             $rc = RecentChange::notifyNew($now, $this->mTitle, $isminor, $user, $summary, $bot, '', strlen($text), $revisionId, $patrolled);
             # Log auto-patrolled edits
             if ($patrolled) {
                 PatrolLog::record($rc, true);
             }
         }
         $user->incEditCount();
         $dbw->commit();
         # Update links, etc.
         $this->editUpdates($text, $summary, $isminor, $now, $revisionId, true);
         # Clear caches
         Article::onArticleCreate($this->mTitle);
         wfRunHooks('ArticleInsertComplete', array(&$this, &$user, $text, $summary, $flags & EDIT_MINOR, null, null, &$flags, $revision));
     }
     # Do updates right now unless deferral was requested
     if (!($flags & EDIT_DEFER_UPDATES)) {
         wfDoUpdates();
     }
     // Return the new revision (or null) to the caller
     $status->value['revision'] = $revision;
     wfRunHooks('ArticleSaveComplete', array(&$this, &$user, $text, $summary, $flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId));
     wfProfileOut(__METHOD__);
     return $status;
 }
Beispiel #17
0
 /**
  * Publish the log entry.
  *
  * @param int $newId Id of the log entry.
  * @param string $to One of: rcandudp (default), rc, udp
  * @return RecentChange|null
  */
 public function publish($newId, $to = 'rcandudp')
 {
     $log = new LogPage($this->getType());
     if ($log->isRestricted()) {
         return null;
     }
     $rc = $this->getRecentChange($newId);
     if ($to === 'rc' || $to === 'rcandudp') {
         $rc->save('pleasedontudp');
     }
     if ($to === 'udp' || $to === 'rcandudp') {
         $rc->notifyRCFeeds();
     }
     // Log the autopatrol if the log entry is patrollable
     if ($this->getIsPatrollable() && $rc->getAttribute('rc_patrolled') === 1) {
         PatrolLog::record($rc, true, $this->getPerformer());
     }
     // Add change tags to the log entry and (if applicable) the associated revision
     $tags = $this->getTags();
     if (!is_null($tags)) {
         $rcId = $rc->getAttribute('rc_id');
         $revId = $this->getAssociatedRevId();
         // Use null if $revId is 0
         ChangeTags::addTags($tags, $rcId, $revId > 0 ? $revId : null, $newId);
     }
     return $rc;
 }
Beispiel #18
0
	/**
	 * Change an existing article or create a new article. Updates RC and all necessary caches,
	 * optionally via the deferred update array.
	 *
	 * @param $content Content: new content
	 * @param string $summary edit summary
	 * @param $flags Integer bitfield:
	 *      EDIT_NEW
	 *          Article is known or assumed to be non-existent, create a new one
	 *      EDIT_UPDATE
	 *          Article is known or assumed to be pre-existing, update it
	 *      EDIT_MINOR
	 *          Mark this edit minor, if the user is allowed to do so
	 *      EDIT_SUPPRESS_RC
	 *          Do not log the change in recentchanges
	 *      EDIT_FORCE_BOT
	 *          Mark the edit a "bot" edit regardless of user rights
	 *      EDIT_DEFER_UPDATES
	 *          Defer some of the updates until the end of index.php
	 *      EDIT_AUTOSUMMARY
	 *          Fill in blank summaries with generated text where possible
	 *
	 * If neither EDIT_NEW nor EDIT_UPDATE is specified, the status of the article will be detected.
	 * If EDIT_UPDATE is specified and the article doesn't exist, the function will return an
	 * edit-gone-missing error. If EDIT_NEW is specified and the article does exist, an
	 * edit-already-exists error will be returned. These two conditions are also possible with
	 * auto-detection due to MediaWiki's performance-optimised locking strategy.
	 *
	 * @param bool|int $baseRevId the revision ID this edit was based off, if any
	 * @param $user User the user doing the edit
	 * @param $serialisation_format String: format for storing the content in the database
	 *
	 * @throws MWException
	 * @return Status object. Possible errors:
	 *     edit-hook-aborted:       The ArticleSave hook aborted the edit but didn't set the fatal flag of $status
	 *     edit-gone-missing:       In update mode, but the article didn't exist
	 *     edit-conflict:           In update mode, the article changed unexpectedly
	 *     edit-no-change:          Warning that the text was the same as before
	 *     edit-already-exists:     In creation mode, but the article already exists
	 *
	 *  Extensions may define additional errors.
	 *
	 *  $return->value will contain an associative array with members as follows:
	 *     new:                     Boolean indicating if the function attempted to create a new article
	 *     revision:                The revision object for the inserted revision, or null
	 *
	 * @since 1.21
	 */
	public function doEditContent( Content $content, $summary, $flags = 0, $baseRevId = false,
								   User $user = null, $serialisation_format = null ) {
		global $wgUser, $wgUseAutomaticEditSummaries, $wgUseRCPatrol, $wgUseNPPatrol;

		// Low-level sanity check
		if ( $this->mTitle->getText() === '' ) {
			throw new MWException( 'Something is trying to edit an article with an empty title' );
		}

		wfProfileIn( __METHOD__ );

		if ( !$content->getContentHandler()->canBeUsedOn( $this->getTitle() ) ) {
			wfProfileOut( __METHOD__ );
			return Status::newFatal( 'content-not-allowed-here',
				ContentHandler::getLocalizedName( $content->getModel() ),
				$this->getTitle()->getPrefixedText() );
		}

		$user = is_null( $user ) ? $wgUser : $user;
		$status = Status::newGood( array() );

		// Load the data from the master database if needed.
		// The caller may already loaded it from the master or even loaded it using
		// SELECT FOR UPDATE, so do not override that using clear().
		$this->loadPageData( 'fromdbmaster' );

		$flags = $this->checkFlags( $flags );

		// handle hook
		$hook_args = array( &$this, &$user, &$content, &$summary,
							$flags & EDIT_MINOR, null, null, &$flags, &$status );

		if ( !wfRunHooks( 'PageContentSave', $hook_args )
			|| !ContentHandler::runLegacyHooks( 'ArticleSave', $hook_args ) ) {

			wfDebug( __METHOD__ . ": ArticleSave or ArticleSaveContent hook aborted save!\n" );

			if ( $status->isOK() ) {
				$status->fatal( 'edit-hook-aborted' );
			}

			wfProfileOut( __METHOD__ );
			return $status;
		}

		// Silently ignore EDIT_MINOR if not allowed
		$isminor = ( $flags & EDIT_MINOR ) && $user->isAllowed( 'minoredit' );
		$bot = $flags & EDIT_FORCE_BOT;

		$old_content = $this->getContent( Revision::RAW ); // current revision's content

		$oldsize = $old_content ? $old_content->getSize() : 0;
		$oldid = $this->getLatest();
		$oldIsRedirect = $this->isRedirect();
		$oldcountable = $this->isCountable();

		$handler = $content->getContentHandler();

		// Provide autosummaries if one is not provided and autosummaries are enabled.
		if ( $wgUseAutomaticEditSummaries && $flags & EDIT_AUTOSUMMARY && $summary == '' ) {
			if ( !$old_content ) {
				$old_content = null;
			}
			$summary = $handler->getAutosummary( $old_content, $content, $flags );
		}

		$editInfo = $this->prepareContentForEdit( $content, null, $user, $serialisation_format );
		$serialized = $editInfo->pst;

		/**
		 * @var Content $content
		 */
		$content = $editInfo->pstContent;
		$newsize = $content->getSize();

		$dbw = wfGetDB( DB_MASTER );
		$now = wfTimestampNow();
		$this->mTimestamp = $now;

		if ( $flags & EDIT_UPDATE ) {
			// Update article, but only if changed.
			$status->value['new'] = false;

			if ( !$oldid ) {
				// Article gone missing
				wfDebug( __METHOD__ . ": EDIT_UPDATE specified but article doesn't exist\n" );
				$status->fatal( 'edit-gone-missing' );

				wfProfileOut( __METHOD__ );
				return $status;
			} elseif ( !$old_content ) {
				// Sanity check for bug 37225
				wfProfileOut( __METHOD__ );
				throw new MWException( "Could not find text for current revision {$oldid}." );
			}

			$revision = new Revision( array(
				'page'       => $this->getId(),
				'title'      => $this->getTitle(), // for determining the default content model
				'comment'    => $summary,
				'minor_edit' => $isminor,
				'text'       => $serialized,
				'len'        => $newsize,
				'parent_id'  => $oldid,
				'user'       => $user->getId(),
				'user_text'  => $user->getName(),
				'timestamp'  => $now,
				'content_model' => $content->getModel(),
				'content_format' => $serialisation_format,
			) ); // XXX: pass content object?!

			$changed = !$content->equals( $old_content );

			if ( $changed ) {
				if ( !$content->isValid() ) {
					wfProfileOut( __METHOD__ );
					throw new MWException( "New content failed validity check!" );
				}

				$dbw->begin( __METHOD__ );

				$prepStatus = $content->prepareSave( $this, $flags, $baseRevId, $user );
				$status->merge( $prepStatus );

				if ( !$status->isOK() ) {
					$dbw->rollback( __METHOD__ );

					wfProfileOut( __METHOD__ );
					return $status;
				}

				$revisionId = $revision->insertOn( $dbw );

				// Update page
				//
				// Note that we use $this->mLatest instead of fetching a value from the master DB
				// during the course of this function. This makes sure that EditPage can detect
				// edit conflicts reliably, either by $ok here, or by $article->getTimestamp()
				// before this function is called. A previous function used a separate query, this
				// creates a window where concurrent edits can cause an ignored edit conflict.
				$ok = $this->updateRevisionOn( $dbw, $revision, $oldid, $oldIsRedirect );

				if ( !$ok ) {
					// Belated edit conflict! Run away!!
					$status->fatal( 'edit-conflict' );

					$dbw->rollback( __METHOD__ );

					wfProfileOut( __METHOD__ );
					return $status;
				}

				wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, $baseRevId, $user ) );
				// Update recentchanges
				if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
					// Mark as patrolled if the user can do so
					$patrolled = $wgUseRCPatrol && !count(
						$this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
					// Add RC row to the DB
					$rc = RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $user, $summary,
						$oldid, $this->getTimestamp(), $bot, '', $oldsize, $newsize,
						$revisionId, $patrolled
					);

					// Log auto-patrolled edits
					if ( $patrolled ) {
						PatrolLog::record( $rc, true, $user );
					}
				}
				$user->incEditCount();
				$dbw->commit( __METHOD__ );
			} else {
				// Bug 32948: revision ID must be set to page {{REVISIONID}} and
				// related variables correctly
				$revision->setId( $this->getLatest() );
			}

			// Update links tables, site stats, etc.
			$this->doEditUpdates(
				$revision,
				$user,
				array(
					'changed' => $changed,
					'oldcountable' => $oldcountable
				)
			);

			if ( !$changed ) {
				$status->warning( 'edit-no-change' );
				$revision = null;
				// Update page_touched, this is usually implicit in the page update
				// Other cache updates are done in onArticleEdit()
				$this->mTitle->invalidateCache();
			}
		} else {
			// Create new article
			$status->value['new'] = true;

			$dbw->begin( __METHOD__ );

			$prepStatus = $content->prepareSave( $this, $flags, $baseRevId, $user );
			$status->merge( $prepStatus );

			if ( !$status->isOK() ) {
				$dbw->rollback( __METHOD__ );

				wfProfileOut( __METHOD__ );
				return $status;
			}

			$status->merge( $prepStatus );

			// Add the page record; stake our claim on this title!
			// This will return false if the article already exists
			$newid = $this->insertOn( $dbw );

			if ( $newid === false ) {
				$dbw->rollback( __METHOD__ );
				$status->fatal( 'edit-already-exists' );

				wfProfileOut( __METHOD__ );
				return $status;
			}

			// Save the revision text...
			$revision = new Revision( array(
				'page'       => $newid,
				'title'      => $this->getTitle(), // for determining the default content model
				'comment'    => $summary,
				'minor_edit' => $isminor,
				'text'       => $serialized,
				'len'        => $newsize,
				'user'       => $user->getId(),
				'user_text'  => $user->getName(),
				'timestamp'  => $now,
				'content_model' => $content->getModel(),
				'content_format' => $serialisation_format,
			) );
			$revisionId = $revision->insertOn( $dbw );

			// Bug 37225: use accessor to get the text as Revision may trim it
			$content = $revision->getContent(); // sanity; get normalized version

			if ( $content ) {
				$newsize = $content->getSize();
			}

			// Update the page record with revision data
			$this->updateRevisionOn( $dbw, $revision, 0 );

			wfRunHooks( 'NewRevisionFromEditComplete', array( $this, $revision, false, $user ) );

			// Update recentchanges
			if ( !( $flags & EDIT_SUPPRESS_RC ) ) {
				// Mark as patrolled if the user can do so
				$patrolled = ( $wgUseRCPatrol || $wgUseNPPatrol ) && !count(
					$this->mTitle->getUserPermissionsErrors( 'autopatrol', $user ) );
				// Add RC row to the DB
				$rc = RecentChange::notifyNew( $now, $this->mTitle, $isminor, $user, $summary, $bot,
					'', $newsize, $revisionId, $patrolled );

				// Log auto-patrolled edits
				if ( $patrolled ) {
					PatrolLog::record( $rc, true, $user );
				}
			}
			$user->incEditCount();
			$dbw->commit( __METHOD__ );

			// Update links, etc.
			$this->doEditUpdates( $revision, $user, array( 'created' => true ) );

			$hook_args = array( &$this, &$user, $content, $summary,
								$flags & EDIT_MINOR, null, null, &$flags, $revision );

			ContentHandler::runLegacyHooks( 'ArticleInsertComplete', $hook_args );
			wfRunHooks( 'PageContentInsertComplete', $hook_args );
		}

		// Do updates right now unless deferral was requested
		if ( !( $flags & EDIT_DEFER_UPDATES ) ) {
			DeferredUpdates::doUpdates();
		}

		// Return the new revision (or null) to the caller
		$status->value['revision'] = $revision;

		$hook_args = array( &$this, &$user, $content, $summary,
							$flags & EDIT_MINOR, null, null, &$flags, $revision, &$status, $baseRevId );

		ContentHandler::runLegacyHooks( 'ArticleSaveComplete', $hook_args );
		wfRunHooks( 'PageContentSaveComplete', $hook_args );

		// Promote user to any groups they meet the criteria for
		$user->addAutopromoteOnceGroups( 'onEdit' );

		wfProfileOut( __METHOD__ );
		return $status;
	}
Beispiel #19
0
 /**
  * Mark this RecentChange as patrolled
  *
  * NOTE: Can also return 'rcpatroldisabled', 'hookaborted' and
  * 'markedaspatrollederror-noautopatrol' as errors
  * @param $user User object doing the action
  * @param $auto Boolean: for automatic patrol
  * @param $force Boolean: ignore any errors (such as permission errors) and
  *   mark the recent change as patrolled anyway (added by Reuben during 
  *   Mediawiki upgrade 1.21).
  * @return array of permissions errors, see Title::getUserPermissionsErrors()
  */
 public function doMarkPatrolled(User $user, $auto = false, $force = false)
 {
     global $wgUseRCPatrol, $wgUseNPPatrol;
     $errors = array();
     // If recentchanges patrol is disabled, only new pages
     // can be patrolled
     if (!$wgUseRCPatrol && (!$wgUseNPPatrol || $this->getAttribute('rc_type') != RC_NEW)) {
         $errors[] = array('rcpatroldisabled');
     }
     // Automatic patrol needs "autopatrol", ordinary patrol needs "patrol"
     if (!$force) {
         $right = $auto ? 'autopatrol' : 'patrol';
         $errors = array_merge($errors, $this->getTitle()->getUserPermissionsErrors($right, $user));
     }
     if (!wfRunHooks('MarkPatrolled', array($this->getAttribute('rc_id'), &$user, false))) {
         $errors[] = array('hookaborted');
     }
     // Users without the 'autopatrol' right can't patrol their
     // own revisions
     if (!$force && $user->getName() == $this->getAttribute('rc_user_text') && !$user->isAllowed('autopatrol')) {
         $errors[] = array('markedaspatrollederror-noautopatrol');
     }
     if ($errors) {
         return $errors;
     }
     // If the change was patrolled already, do nothing
     if ($this->getAttribute('rc_patrolled')) {
         return array();
     }
     // Actually set the 'patrolled' flag in RC
     $this->reallyMarkPatrolled();
     // Log this patrol event
     PatrolLog::record($this, $auto, $user);
     wfRunHooks('MarkPatrolledComplete', array($this->getAttribute('rc_id'), &$user, false));
     // JRS, upgrade 1.21: adding hook used for GoodRevision, DailyEdits and
     // email notifications
     $t = $this->getTitle();
     $revId = $this->getAttribute('rc_this_oldid');
     $a = new Article($t, $revId);
     $rcid = $this->getAttribute('rc_id');
     wfRunHooks('MarkPatrolledDB', array(&$rcid, &$a));
     return array();
 }
Beispiel #20
0
 /**
  * Mark this RecentChange as patrolled
  *
  * NOTE: Can also return 'rcpatroldisabled', 'hookaborted' and 'markedaspatrollederror-noautopatrol' as errors
  * @param $auto Boolean: for automatic patrol
  * @return array of permissions errors, see Title::getUserPermissionsErrors()
  */
 public function doMarkPatrolled($auto = false)
 {
     global $wgUser, $wgUseRCPatrol, $wgUseNPPatrol;
     $errors = array();
     // If recentchanges patrol is disabled, only new pages
     // can be patrolled
     if (!$wgUseRCPatrol && (!$wgUseNPPatrol || $this->getAttribute('rc_type') != RC_NEW)) {
         $errors[] = array('rcpatroldisabled');
     }
     // Automatic patrol needs "autopatrol", ordinary patrol needs "patrol"
     $right = $auto ? 'autopatrol' : 'patrol';
     $errors = array_merge($errors, $this->getTitle()->getUserPermissionsErrors($right, $wgUser));
     if (!wfRunHooks('MarkPatrolled', array($this->getAttribute('rc_id'), &$wgUser, false))) {
         $errors[] = array('hookaborted');
     }
     // Users without the 'autopatrol' right can't patrol their
     // own revisions
     if ($wgUser->getName() == $this->getAttribute('rc_user_text') && !$wgUser->isAllowed('autopatrol')) {
         $errors[] = array('markedaspatrollederror-noautopatrol');
     }
     if ($errors) {
         return $errors;
     }
     // If the change was patrolled already, do nothing
     if ($this->getAttribute('rc_patrolled')) {
         return array();
     }
     // Actually set the 'patrolled' flag in RC
     $this->reallyMarkPatrolled();
     // Log this patrol event
     PatrolLog::record($this, $auto);
     wfRunHooks('MarkPatrolledComplete', array($this->getAttribute('rc_id'), &$wgUser, false));
     return array();
 }
Beispiel #21
0
 /**
  * @static
  * @return HTML string
  */
 public static function actionText($type, $action, $title = NULL, $skin = NULL, $params = array(), $filterWikilinks = false)
 {
     global $wgLang, $wgContLang, $wgLogActions, $wgMessageCache;
     $wgMessageCache->loadAllMessages();
     $key = "{$type}/{$action}";
     # Defer patrol log to PatrolLog class
     if ($key == 'patrol/patrol') {
         return PatrolLog::makeActionText($title, $params, $skin);
     }
     if (isset($wgLogActions[$key])) {
         if (is_null($title)) {
             $rv = wfMsg($wgLogActions[$key]);
         } else {
             $titleLink = self::getTitleLink($type, $skin, $title, $params);
             if ($key == 'rights/rights') {
                 if ($skin) {
                     $rightsnone = wfMsg('rightsnone');
                     foreach ($params as &$param) {
                         $groupArray = array_map('trim', explode(',', $param));
                         $groupArray = array_map(array('User', 'getGroupName'), $groupArray);
                         $param = $wgLang->listToText($groupArray);
                     }
                 } else {
                     $rightsnone = wfMsgForContent('rightsnone');
                 }
                 if (!isset($params[0]) || trim($params[0]) == '') {
                     $params[0] = $rightsnone;
                 }
                 if (!isset($params[1]) || trim($params[1]) == '') {
                     $params[1] = $rightsnone;
                 }
             }
             if (count($params) == 0) {
                 if ($skin) {
                     $rv = wfMsg($wgLogActions[$key], $titleLink);
                 } else {
                     $rv = wfMsgForContent($wgLogActions[$key], $titleLink);
                 }
             } else {
                 $details = '';
                 array_unshift($params, $titleLink);
                 if (preg_match('/^(block|suppress)\\/(block|reblock)$/', $key)) {
                     if ($skin) {
                         $params[1] = '<span title="' . htmlspecialchars($params[1]) . '">' . $wgLang->translateBlockExpiry($params[1]) . '</span>';
                     } else {
                         $params[1] = $wgContLang->translateBlockExpiry($params[1]);
                     }
                     $params[2] = isset($params[2]) ? self::formatBlockFlags($params[2], is_null($skin)) : '';
                 } else {
                     if ($type == 'protect' && count($params) == 3) {
                         $details .= " {$params[1]}";
                         // restrictions and expiries
                         if ($params[2]) {
                             if ($skin) {
                                 $details .= ' [' . wfMsg('protect-summary-cascade') . ']';
                             } else {
                                 $details .= ' [' . wfMsgForContent('protect-summary-cascade') . ']';
                             }
                         }
                     } else {
                         if ($type == 'move' && count($params) == 3) {
                             if ($params[2]) {
                                 if ($skin) {
                                     $details .= ' [' . wfMsg('move-redirect-suppressed') . ']';
                                 } else {
                                     $details .= ' [' . wfMsgForContent('move-redirect-suppressed') . ']';
                                 }
                             }
                         }
                     }
                 }
                 $rv = wfMsgReal($wgLogActions[$key], $params, true, !$skin) . $details;
             }
         }
     } else {
         global $wgLogActionsHandlers;
         if (isset($wgLogActionsHandlers[$key])) {
             $args = func_get_args();
             $rv = call_user_func_array($wgLogActionsHandlers[$key], $args);
         } else {
             wfDebug("LogPage::actionText - unknown action {$key}\n");
             $rv = "{$action}";
         }
     }
     // For the perplexed, this feature was added in r7855 by Erik.
     //  The feature was added because we liked adding [[$1]] in our log entries
     //  but the log entries are parsed as Wikitext on RecentChanges but as HTML
     //  on Special:Log. The hack is essentially that [[$1]] represented a link
     //  to the title in question. The first parameter to the HTML version (Special:Log)
     //  is that link in HTML form, and so this just gets rid of the ugly [[]].
     //  However, this is a horrible hack and it doesn't work like you expect if, say,
     //  you want to link to something OTHER than the title of the log entry.
     //  The real problem, which Erik was trying to fix (and it sort-of works now) is
     //  that the same messages are being treated as both wikitext *and* HTML.
     if ($filterWikilinks) {
         $rv = str_replace("[[", "", $rv);
         $rv = str_replace("]]", "", $rv);
     }
     return $rv;
 }