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; }
/** * 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; }
/** * 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; }
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; }
/** * 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; }
/** * 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); }
/** * 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()); } }
/** * 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)); }
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)); } }
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; }
/** * 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; }
/** * 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 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(); }
/** * 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(); }
/** * 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); }