// Was anything restored at all? if ($restored == 0) { print "Nothing was restored\n"; exit(1); } if ($revision) { // Attach the latest revision to the page... $wasnew = $article->updateIfNewerOn($dbw, $revision, $previousRevId); if ($newid || $wasnew) { // Update site stats, link tables, etc $article->createUpdates($revision); } if ($newid) { Article::onArticleCreate($page); } else { Article::onArticleEdit($page); } if ($page->getNamespace() == NS_IMAGE) { $update = new HTMLCacheUpdate($page, 'imagelinks'); $update->doUpdate(); } } else { // Revision couldn't be created. This is very weird print "We got an unknown error\n"; exit(1); } # Now that it's safely stored, take it out of the archive $dbw->delete('archive', array('ar_namespace' => $page->getNamespace(), 'ar_title' => $page->getDBkey(), $oldones), __METHOD__); print $page->getPrefixedText(); if ($restored) { print "\n";
/** * 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 importOldRevision() { $dbw = wfGetDB(DB_MASTER); # Sneak a single revision into place $user = User::newFromName($this->getUser()); if ($user) { $userId = intval($user->getId()); $userText = $user->getName(); } else { $userId = 0; $userText = $this->getUser(); } // avoid memory leak...? $linkCache = LinkCache::singleton(); $linkCache->clear(); $article = new Article($this->title); $pageId = $article->getId(); if ($pageId == 0) { # must create the page... $pageId = $article->insertOn($dbw); $created = true; } else { $created = false; $prior = $dbw->selectField('revision', '1', array('rev_page' => $pageId, 'rev_timestamp' => $dbw->timestamp($this->timestamp), 'rev_user_text' => $userText, 'rev_comment' => $this->getComment()), __METHOD__); if ($prior) { // FIXME: this could fail slightly for multiple matches :P wfDebug(__METHOD__ . ": skipping existing revision for [[" . $this->title->getPrefixedText() . "]], timestamp " . $this->timestamp . "\n"); return false; } } # FIXME: Use original rev_id optionally (better for backups) # Insert the row $revision = new Revision(array('page' => $pageId, 'text' => $this->getText(), 'comment' => $this->getComment(), 'user' => $userId, 'user_text' => $userText, 'timestamp' => $this->timestamp, 'minor_edit' => $this->minor)); $revId = $revision->insertOn($dbw); $changed = $article->updateIfNewerOn($dbw, $revision); # To be on the safe side... $tempTitle = $GLOBALS['wgTitle']; $GLOBALS['wgTitle'] = $this->title; if ($created) { wfDebug(__METHOD__ . ": running onArticleCreate\n"); Article::onArticleCreate($this->title); wfDebug(__METHOD__ . ": running create updates\n"); $article->createUpdates($revision); } elseif ($changed) { wfDebug(__METHOD__ . ": running onArticleEdit\n"); Article::onArticleEdit($this->title); wfDebug(__METHOD__ . ": running edit updates\n"); $article->editUpdates($this->getText(), $this->getComment(), $this->minor, $this->timestamp, $revId); } $GLOBALS['wgTitle'] = $tempTitle; 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; 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 = $wgUser->isAllowed('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); } $text = $this->preSaveTransform($text); $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; if (0 != strcmp($text, $oldtext)) { $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 ($wgUser->isAllowed('autopatrol')) { RecentChange::markPatrolled($rcid); } } $wgUser->incEditCount(); $dbw->commit(); } } else { // 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. $changed = strcmp($oldtext, $text) != 0; $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 ($wgUser->isAllowed('autopatrol')) { RecentChange::markPatrolled($rcid); } } $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)); } if ($good && !($flags & EDIT_DEFER_UPDATES)) { wfDoUpdates(); } wfRunHooks('ArticleSaveComplete', array(&$this, &$wgUser, $text, $summary, $flags & EDIT_MINOR, null, null, &$flags)); wfProfileOut(__METHOD__); return $good; }
/** * AJAX helper called from view mode to save gallery data * @author Marooned */ public static function saveGalleryDataByHash($hash, $wikitext, $starttime) { global $wgTitle, $wgUser; wfProfileIn(__METHOD__); wfDebug(__METHOD__ . ": {$wikitext}\n"); $result = array(); // save changed gallery $rev = Revision::newFromTitle($wgTitle); // try to fix fatal (article has been removed since user opened the page) if (empty($rev)) { $result['info'] = 'conflict'; wfDebug(__METHOD__ . ": revision is empty\n"); wfProfileOut(__METHOD__); return $result; } $articleWikitext = $rev->getText(); $gallery = ''; preg_match_all('%<gallery([^>]*)>(.*?)</gallery>%s', $articleWikitext, $matches, PREG_PATTERN_ORDER); for ($i = 0; $i < count($matches[0]); $i++) { $attribs = Sanitizer::decodeTagAttributes($matches[1][$i]); //count hash from attribs and content if (md5($matches[2][$i] . implode('', $attribs)) == $hash) { $gallery = $matches[0][$i]; break; } } if (empty($gallery)) { $result['info'] = 'conflict'; wfDebug(__METHOD__ . ": conflict found\n"); } else { $articleWikitext = str_replace($gallery, $wikitext, $articleWikitext); //saving if ($wgTitle->userCan('edit') && !$wgUser->isBlocked()) { $result = null; $article = new Article($wgTitle); $editPage = new EditPage($article); $editPage->edittime = $article->getTimestamp(); $editPage->starttime = $starttime; $editPage->textbox1 = $articleWikitext; $editPage->summary = wfMsgForContent('wikiaPhotoGallery-edit-summary'); // watch all my edits / preserve watchlist (RT #59138) if ($wgUser->getOption('watchdefault')) { $editPage->watchthis = true; } else { $editPage->watchthis = $editPage->mTitle->userIsWatching(); } $bot = $wgUser->isAllowed('bot'); $status = $editPage->internalAttemptSave($result, $bot); $retval = $status->value; Wikia::log(__METHOD__, "editpage", "Returned value {$retval}"); switch ($retval) { case EditPage::AS_SUCCESS_UPDATE: case EditPage::AS_SUCCESS_NEW_ARTICLE: $wgTitle->invalidateCache(); Article::onArticleEdit($wgTitle); $result['info'] = 'ok'; break; case EditPage::AS_SPAM_ERROR: $result['error'] = wfMsg('spamprotectiontext') . '<p>( Call #4 )</p>'; break; default: $result['error'] = wfMsg('wikiaPhotoGallery-edit-abort'); } } else { $result['error'] = wfMsg('wikiaPhotoGallery-error-user-rights'); } if (isset($result['error'])) { $result['errorCaption'] = wfMsg('wikiaPhotoGallery-error-caption'); } //end of saving wfDebug(__METHOD__ . ": saving from view mode done\n"); // commit (RT #48304) $dbw = wfGetDB(DB_MASTER); $dbw->commit(); } wfProfileOut(__METHOD__); return $result; }
function importOldRevision() { $dbw = wfGetDB(DB_MASTER); # Sneak a single revision into place $user = User::newFromName($this->getUser()); if ($user) { $userId = intval($user->getId()); $userText = $user->getName(); } else { $userId = 0; $userText = $this->getUser(); } // avoid memory leak...? $linkCache =& LinkCache::singleton(); $linkCache->clear(); $article = new Article($this->title); $pageId = $article->getId(); if ($pageId == 0) { # must create the page... $pageId = $article->insertOn($dbw); $created = true; } else { $created = false; $prior = Revision::loadFromTimestamp($dbw, $this->title, $this->timestamp); if (!is_null($prior)) { // FIXME: this could fail slightly for multiple matches :P wfDebug(__METHOD__ . ": skipping existing revision for [[" . $this->title->getPrefixedText() . "]], timestamp " . $this->timestamp . "\n"); return false; } } # FIXME: Use original rev_id optionally # FIXME: blah blah blah #if( $numrows > 0 ) { # return wfMsg( "importhistoryconflict" ); #} # Insert the row $revision = new Revision(array('page' => $pageId, 'text' => $this->getText(), 'comment' => $this->getComment(), 'user' => $userId, 'user_text' => $userText, 'timestamp' => $this->timestamp, 'minor_edit' => $this->minor)); $revId = $revision->insertOn($dbw); $changed = $article->updateIfNewerOn($dbw, $revision); if ($created) { wfDebug(__METHOD__ . ": running onArticleCreate\n"); Article::onArticleCreate($this->title); wfDebug(__METHOD__ . ": running create updates\n"); $article->createUpdates($revision); } elseif ($changed) { wfDebug(__METHOD__ . ": running onArticleEdit\n"); Article::onArticleEdit($this->title); wfDebug(__METHOD__ . ": running edit updates\n"); $article->editUpdates($this->getText(), $this->getComment(), $this->minor, $this->timestamp, $revId); } return true; }
/** * This is the meaty bit -- restores archived revisions of the given page * to the cur/old tables. If the page currently exists, all revisions will * be stuffed into old, otherwise the most recent will go into cur. * * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete. * @param string $comment * @param array $fileVersions * * @return mixed number of revisions restored or false on failure */ private function undeleteRevisions($timestamps) { if (wfReadOnly()) { return false; } $restoreAll = empty($timestamps); $dbw = wfGetDB(DB_MASTER); # Does this page already exist? We'll have to update it... $article = new Article($this->title); $options = 'FOR UPDATE'; $page = $dbw->selectRow('page', array('page_id', 'page_latest'), array('page_namespace' => $this->title->getNamespace(), 'page_title' => $this->title->getDBkey()), __METHOD__, $options); if ($page) { # Page already exists. Import the history, and if necessary # we'll update the latest revision field in the record. $newid = 0; $pageId = $page->page_id; $previousRevId = $page->page_latest; } else { # Have to create a new article... $newid = $article->insertOn($dbw); $pageId = $newid; $previousRevId = 0; } if ($restoreAll) { $oldones = '1 = 1'; # All revisions... } else { $oldts = implode(',', array_map(array(&$dbw, 'addQuotes'), array_map(array(&$dbw, 'timestamp'), $timestamps))); $oldones = "ar_timestamp IN ( {$oldts} )"; } /** * Restore each revision... */ $result = $dbw->select('archive', array('ar_rev_id', 'ar_text', 'ar_comment', 'ar_user', 'ar_user_text', 'ar_timestamp', 'ar_minor_edit', 'ar_flags', 'ar_text_id', 'ar_page_id', 'ar_len'), array('ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), $oldones), __METHOD__, array('ORDER BY' => 'ar_timestamp')); if ($dbw->numRows($result) < count($timestamps)) { wfDebug(__METHOD__ . ": couldn't find all requested rows\n"); return false; } $revision = null; $restored = 0; while ($row = $dbw->fetchObject($result)) { if ($row->ar_text_id) { // Revision was deleted in 1.5+; text is in // the regular text table, use the reference. // Specify null here so the so the text is // dereferenced for page length info if needed. $revText = null; } else { // Revision was deleted in 1.4 or earlier. // Text is squashed into the archive row, and // a new text table entry will be created for it. $revText = Revision::getRevisionText($row, 'ar_'); } $revision = new Revision(array('page' => $pageId, 'id' => $row->ar_rev_id, 'text' => $revText, 'comment' => $row->ar_comment, 'user' => $row->ar_user, 'user_text' => $row->ar_user_text, 'timestamp' => $row->ar_timestamp, 'minor_edit' => $row->ar_minor_edit, 'text_id' => $row->ar_text_id, 'len' => $row->ar_len)); $revision->insertOn($dbw); $restored++; wfRunHooks('ArticleRevisionUndeleted', array(&$this->title, $revision, $row->ar_page_id)); } // Was anything restored at all? if ($restored == 0) { return 0; } if ($revision) { // Attach the latest revision to the page... $wasnew = $article->updateIfNewerOn($dbw, $revision, $previousRevId); if ($newid || $wasnew) { // Update site stats, link tables, etc $article->createUpdates($revision); } if ($newid) { wfRunHooks('ArticleUndelete', array(&$this->title, true)); Article::onArticleCreate($this->title); } else { wfRunHooks('ArticleUndelete', array(&$this->title, false)); Article::onArticleEdit($this->title); } if ($this->title->getNamespace() == NS_IMAGE) { $update = new HTMLCacheUpdate($this->title, 'imagelinks'); $update->doUpdate(); } } else { // Revision couldn't be created. This is very weird return self::UNDELETE_UNKNOWNERR; } # Now that it's safely stored, take it out of the archive $dbw->delete('archive', array('ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), $oldones), __METHOD__); return $restored; }
/** * This is the meaty bit -- restores archived revisions of the given page * to the cur/old tables. If the page currently exists, all revisions will * be stuffed into old, otherwise the most recent will go into cur. * * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete. * @param string $comment * @param array $fileVersions * @param bool $unsuppress, remove all ar_deleted/fa_deleted restrictions of seletected revs * * @return mixed number of revisions restored or false on failure */ private function undeleteRevisions($timestamps, $unsuppress = false, $comment = '') { if (wfReadOnly()) { return false; } $restoreAll = empty($timestamps); $dbw = wfGetDB(DB_MASTER); # Does this page already exist? We'll have to update it... $article = new Article($this->title); $options = 'FOR UPDATE'; // lock page $page = $dbw->selectRow('page', array('page_id', 'page_latest'), array('page_namespace' => $this->title->getNamespace(), 'page_title' => $this->title->getDBkey()), __METHOD__, $options); if ($page) { $makepage = false; # Page already exists. Import the history, and if necessary # we'll update the latest revision field in the record. $newid = 0; $pageId = $page->page_id; $previousRevId = $page->page_latest; # Get the time span of this page $previousTimestamp = $dbw->selectField('revision', 'rev_timestamp', array('rev_id' => $previousRevId), __METHOD__); if ($previousTimestamp === false) { wfDebug(__METHOD__ . ": existing page refers to a page_latest that does not exist\n"); return 0; } } else { # Have to create a new article... $makepage = true; $previousRevId = 0; $previousTimestamp = 0; } if ($restoreAll) { $oldones = '1 = 1'; # All revisions... } else { $oldts = implode(',', array_map(array(&$dbw, 'addQuotes'), array_map(array(&$dbw, 'timestamp'), $timestamps))); $oldones = "ar_timestamp IN ( {$oldts} )"; } /** * Select each archived revision... */ $result = $dbw->select('archive', array('ar_rev_id', 'ar_text', 'ar_comment', 'ar_user', 'ar_user_text', 'ar_timestamp', 'ar_minor_edit', 'ar_flags', 'ar_text_id', 'ar_deleted', 'ar_page_id', 'ar_len'), array('ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), $oldones), __METHOD__, array('ORDER BY' => 'ar_timestamp')); $ret = $dbw->resultObject($result); $rev_count = $dbw->numRows($result); if (!$rev_count) { wfDebug(__METHOD__ . ": no revisions to restore\n"); return false; // ??? } $ret->seek($rev_count - 1); // move to last $row = $ret->fetchObject(); // get newest archived rev $ret->seek(0); // move back if ($makepage) { // Check the state of the newest to-be version... if (!$unsuppress && $row->ar_deleted & Revision::DELETED_TEXT) { return false; // we can't leave the current revision like this! } // Safe to insert now... $newid = $article->insertOn($dbw); $pageId = $newid; } else { // Check if a deleted revision will become the current revision... if ($row->ar_timestamp > $previousTimestamp) { // Check the state of the newest to-be version... if (!$unsuppress && $row->ar_deleted & Revision::DELETED_TEXT) { return false; // we can't leave the current revision like this! } } } $revision = null; $restored = 0; while ($row = $ret->fetchObject()) { // Check for key dupes due to shitty archive integrity. if ($row->ar_rev_id) { $exists = $dbw->selectField('revision', '1', array('rev_id' => $row->ar_rev_id), __METHOD__); if ($exists) { continue; } // don't throw DB errors } // Insert one revision at a time...maintaining deletion status // unless we are specifically removing all restrictions... $revision = Revision::newFromArchiveRow($row, array('page' => $pageId, 'deleted' => $unsuppress ? 0 : $row->ar_deleted)); $revision->insertOn($dbw); $restored++; wfRunHooks('ArticleRevisionUndeleted', array(&$this->title, $revision, $row->ar_page_id)); } # Now that it's safely stored, take it out of the archive $dbw->delete('archive', array('ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), $oldones), __METHOD__); // Was anything restored at all? if ($restored == 0) { return 0; } if ($revision) { // Attach the latest revision to the page... $wasnew = $article->updateIfNewerOn($dbw, $revision, $previousRevId); if ($newid || $wasnew) { // Update site stats, link tables, etc $article->createUpdates($revision); } if ($newid) { wfRunHooks('ArticleUndelete', array(&$this->title, true, $comment)); Article::onArticleCreate($this->title); } else { wfRunHooks('ArticleUndelete', array(&$this->title, false, $comment)); Article::onArticleEdit($this->title); } if ($this->title->getNamespace() == NS_FILE) { $update = new HTMLCacheUpdate($this->title, 'imagelinks'); $update->doUpdate(); } } else { // Revision couldn't be created. This is very weird return self::UNDELETE_UNKNOWNERR; } return $restored; }
/** * Revert a modification */ function rollback() { global $wgUser, $wgOut, $wgRequest; $fname = 'Article::rollback'; if (!$wgUser->isAllowed('rollback')) { $wgOut->sysopRequired(); return; } if (wfReadOnly()) { $wgOut->readOnlyPage($this->getContent(true)); return; } if (!$wgUser->matchEditToken($wgRequest->getVal('token'), array($this->mTitle->getPrefixedText(), $wgRequest->getVal('from')))) { $wgOut->setPageTitle(wfMsg('rollbackfailed')); $wgOut->addWikiText(wfMsg('sessionfailure')); return; } $dbw =& wfGetDB(DB_MASTER); # Enhanced rollback, marks edits rc_bot=1 $bot = $wgRequest->getBool('bot'); # Replace all this user's current edits with the next one down $tt = $this->mTitle->getDBKey(); $n = $this->mTitle->getNamespace(); # Get the last editor, lock table exclusively $dbw->begin(); $current = Revision::newFromTitle($this->mTitle); if (is_null($current)) { # Something wrong... no page? $dbw->rollback(); $wgOut->addHTML(wfMsg('notanarticle')); return; } $from = str_replace('_', ' ', $wgRequest->getVal('from')); if ($from != $current->getUserText()) { $wgOut->setPageTitle(wfmsg('rollbackfailed')); $wgOut->addWikiText(wfMsg('alreadyrolled', htmlspecialchars($this->mTitle->getPrefixedText()), htmlspecialchars($from), htmlspecialchars($current->getUserText()))); if ($current->getComment() != '') { $wgOut->addHTML(wfMsg('editcomment', htmlspecialchars($current->getComment()))); } return; } # Get the last edit not by this guy $user = IntVal($current->getUser()); $user_text = $dbw->addQuotes($current->getUserText()); $s = $dbw->selectRow('revision', array('rev_id', 'rev_timestamp'), array('rev_page' => $current->getPage(), "rev_user <> {$user} OR rev_user_text <> {$user_text}"), $fname, array('USE INDEX' => 'page_timestamp', 'ORDER BY' => 'rev_timestamp DESC')); if ($s === false) { # Something wrong $dbw->rollback(); $wgOut->setPageTitle(wfMsg('rollbackfailed')); $wgOut->addHTML(wfMsg('cantrollback')); return; } if ($bot) { # Mark all reverted edits as bot $dbw->update('recentchanges', array('rc_bot' => 1), array('rc_cur_id' => $current->getPage(), 'rc_user_text' => $current->getUserText(), "rc_timestamp > '{$s->rev_timestamp}'"), $fname); } # Save it! $target = Revision::newFromId($s->rev_id); $newcomment = wfMsgForContent('revertpage', $target->getUserText(), $from); $wgOut->setPagetitle(wfMsg('actioncomplete')); $wgOut->setRobotpolicy('noindex,nofollow'); $wgOut->addHTML('<h2>' . htmlspecialchars($newcomment) . "</h2>\n<hr />\n"); $this->updateArticle($target->getText(), $newcomment, 1, $this->mTitle->userIsWatching(), $bot); Article::onArticleEdit($this->mTitle); $dbw->commit(); $wgOut->returnToMain(false); }
/** * Create new article * * When successful returns title object of created article. If not, returns EditPage error code */ protected function createArticle($title, $content, $summary) { global $wgUser; wfProfileIn(__METHOD__); self::log(__METHOD__, "creating article '{$title}'"); //self::log(__METHOD__, array($title, $content, $summary)); $ret = false; // title object for new article $newTitle = Title::newFromText($title); if (!empty($newTitle) && !empty($wgUser) && $newTitle->userCan('edit') && !$wgUser->isBlocked()) { $article = new Article($newTitle); $editPage = new EditPage($article); $editPage->edittime = $article->getTimestamp(); $editPage->textbox1 = $content; $editPage->summary = $summary; $editPage->recreate = true; $result = null; $bot = $wgUser->isAllowed('bot'); // do edit $status = $editPage->internalAttemptSave($result, $bot); $ret = $status->value; // creating new article if ($ret == EditPage::AS_SUCCESS_NEW_ARTICLE) { // edit successful $newTitle->invalidateCache(); Article::onArticleEdit($newTitle); self::log(__METHOD__, 'success!'); $ret = $newTitle; } elseif ($ret == EditPage::AS_SPAM_ERROR) { self::log(__METHOD__, 'spam found!'); } else { self::log(__METHOD__, 'edit aborted'); } } else { self::log(__METHOD__, 'user not allowed to edit'); $ret = EditPage::AS_USER_CANNOT_EDIT; } if (is_numeric($ret)) { self::log(__METHOD__, "failed with error code #{$ret}"); } wfProfileOut(__METHOD__); return $ret; }
/** * This is the meaty bit -- restores archived revisions of the given page * to the cur/old tables. If the page currently exists, all revisions will * be stuffed into old, otherwise the most recent will go into cur. * The deletion log will be updated with an undeletion notice. * * Returns true on success. * * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete. * @return bool */ function undelete($timestamps) { global $wgUser, $wgOut, $wgLang, $wgDeferredUpdateList; global $wgUseSquid, $wgInternalServer, $wgLinkCache; global $wgDBtype; $fname = "doUndeleteArticle"; $restoreAll = empty($timestamps); $restoreRevisions = count($timestamps); $dbw =& wfGetDB(DB_MASTER); extract($dbw->tableNames('page', 'archive')); # Does this page already exist? We'll have to update it... $article = new Article($this->title); $options = $wgDBtype == 'PostgreSQL' ? '' : 'FOR UPDATE'; $page = $dbw->selectRow('page', array('page_id', 'page_latest'), array('page_namespace' => $this->title->getNamespace(), 'page_title' => $this->title->getDBkey()), $fname, $options); if ($page) { # Page already exists. Import the history, and if necessary # we'll update the latest revision field in the record. $newid = 0; $pageId = $page->page_id; $previousRevId = $page->page_latest; $previousTimestamp = $page->rev_timestamp; } else { # Have to create a new article... $newid = $article->insertOn($dbw); $pageId = $newid; $previousRevId = 0; $previousTimestamp = 0; } if ($restoreAll) { $oldones = '1'; # All revisions... } else { $oldts = implode(',', array_map(array(&$dbw, 'addQuotes'), array_map(array(&$dbw, 'timestamp'), $timestamps))); $oldones = "ar_timestamp IN ( {$oldts} )"; } /** * Restore each revision... */ $result = $dbw->select('archive', array('ar_rev_id', 'ar_text', 'ar_comment', 'ar_user', 'ar_user_text', 'ar_timestamp', 'ar_minor_edit', 'ar_flags', 'ar_text_id'), array('ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), $oldones), $fname, array('ORDER BY' => 'ar_timestamp')); $revision = null; while ($row = $dbw->fetchObject($result)) { $revision = new Revision(array('page' => $pageId, 'id' => $row->ar_rev_id, 'text' => Revision::getRevisionText($row, 'ar_'), 'comment' => $row->ar_comment, 'user' => $row->ar_user, 'user_text' => $row->ar_user_text, 'timestamp' => $row->ar_timestamp, 'minor_edit' => $row->ar_minor_edit, 'text_id' => $row->ar_text_id)); $revision->insertOn($dbw); } if ($revision) { # FIXME: Update latest if newer as well... if ($newid) { # FIXME: update article count if changed... $article->updateRevisionOn($dbw, $revision, $previousRevId); # Finally, clean up the link tables $wgLinkCache = new LinkCache(); # Select for update $wgLinkCache->forUpdate(true); # Create a dummy OutputPage to update the outgoing links $dummyOut = new OutputPage(); $dummyOut->addWikiText($revision->getText()); $u = new LinksUpdate($newid, $this->title->getPrefixedDBkey()); array_push($wgDeferredUpdateList, $u); #TODO: SearchUpdate, etc. } if ($newid) { Article::onArticleCreate($this->title); } else { Article::onArticleEdit($this->title); } } else { # Something went terribly worong! } # Now that it's safely stored, take it out of the archive $dbw->delete('archive', array('ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), $oldones), $fname); # Touch the log! $log = new LogPage('delete'); if ($restoreAll) { $reason = ''; } else { $reason = wfMsgForContent('undeletedrevisions', $restoreRevisions); } $log->addEntry('restore', $this->title, $reason); return true; }
/** * Save categories sent via AJAX into article */ public function save() { wfProfileIn(__METHOD__); $articleId = $this->request->getVal('articleId', 0); $categories = $this->request->getVal('categories', array()); $response = array(); $title = Title::newFromID($articleId); if (wfReadOnly()) { $response['error'] = wfMessage('categoryselect-error-db-locked')->text(); } else { if (is_null($title)) { $response['error'] = wfMessage('categoryselect-error-article-doesnt-exist', $articleId)->text(); } else { if (!$title->userCan('edit') || $this->wg->User->isBlocked()) { $response['error'] = wfMessage('categoryselect-error-user-rights')->text(); } else { if (!empty($categories) && is_array($categories)) { Wikia::setVar('EditFromViewMode', 'CategorySelect'); $article = new Article($title); $wikitext = $article->fetchContent(); // Pull in categories from templates inside of the article (BugId:100980) $options = new ParserOptions(); $preprocessedWikitext = ParserPool::preprocess($wikitext, $title, $options); $preprocessedData = CategoryHelper::extractCategoriesFromWikitext($preprocessedWikitext, true); // Compare the new categories with those already in the article to weed out duplicates $newCategories = CategoryHelper::getDiffCategories($preprocessedData['categories'], $categories); // Append the new categories to the end of the article wikitext $wikitext .= CategoryHelper::changeFormat($newCategories, 'array', 'wikitext'); // Update the array of categories for the front-end $categories = array_merge($preprocessedData['categories'], $newCategories); $dbw = wfGetDB(DB_MASTER); $dbw->begin(); $editPage = new EditPage($article); $editPage->edittime = $article->getTimestamp(); $editPage->recreate = true; $editPage->textbox1 = $wikitext; $editPage->summary = wfMessage('categoryselect-edit-summary')->inContentLanguage()->text(); $editPage->watchthis = $editPage->mTitle->userIsWatching(); $bot = $this->wg->User->isAllowed('bot'); $status = $editPage->internalAttemptSave($result, $bot)->value; $response['status'] = $status; switch ($status) { case EditPage::AS_SUCCESS_UPDATE: case EditPage::AS_SUCCESS_NEW_ARTICLE: $dbw->commit(); $title->invalidateCache(); Article::onArticleEdit($title); $response['html'] = $this->app->renderView('CategorySelectController', 'categories', array('categories' => $categories)); wfRunHooks('CategorySelectSave', array($title, $newCategories)); break; case EditPage::AS_SPAM_ERROR: $dbw->rollback(); $response['error'] = wfMessage('spamprotectiontext')->text() . '<p>( Case #8 )</p>'; break; default: $dbw->rollback(); $response['error'] = wfMessage('categoryselect-error-edit-abort')->text(); } } } } } $this->response->setData($response); wfProfileOut(__METHOD__); }
/** * Save categories sent via AJAX into article * * @author Maciej Błaszkowski <marooned at wikia-inc.com> */ function CategorySelectAjaxSaveCategories($articleId, $categories) { global $wgUser; if (wfReadOnly()) { $result['error'] = wfMsg('categoryselect-error-db-locked'); return json_encode($result); } wfProfileIn(__METHOD__); Wikia::setVar('EditFromViewMode', 'CategorySelect'); $categories = CategorySelectChangeFormat($categories, 'json', 'wiki'); if ($categories == '') { $result['info'] = 'Nothing to add.'; } else { $title = Title::newFromID($articleId); if (is_null($title)) { $result['error'] = wfMsg('categoryselect-error-not-exist', $articleId); } else { if ($title->userCan('edit') && !$wgUser->isBlocked()) { $result = null; $article = new Article($title); $article_text = $article->fetchContent(); $article_text .= $categories; $dbw = wfGetDB(DB_MASTER); $dbw->begin(); $editPage = new EditPage($article); $editPage->edittime = $article->getTimestamp(); $editPage->recreate = true; $editPage->textbox1 = $article_text; $editPage->summary = wfMsgForContent('categoryselect-edit-summary'); $editPage->watchthis = $editPage->mTitle->userIsWatching(); $bot = $wgUser->isAllowed('bot'); $status = $editPage->internalAttemptSave($result, $bot); $retval = $status->value; Wikia::log(__METHOD__, "editpage", "Returned value {$retval}"); switch ($retval) { case EditPage::AS_SUCCESS_UPDATE: case EditPage::AS_SUCCESS_NEW_ARTICLE: $dbw->commit(); $title->invalidateCache(); Article::onArticleEdit($title); $skin = RequestContext::getMain()->getSkin(); // return HTML with new categories // OutputPage::tryParserCache become deprecated in MW1.17 and removed in MW1.18 (BugId:30443) $parserOutput = ParserCache::singleton()->get($article, $article->getParserOptions()); if ($parserOutput !== false) { $skin->getOutput()->addParserOutput($parserOutput); } $cats = $skin->getCategoryLinks(); $result['info'] = 'ok'; $result['html'] = $cats; break; case EditPage::AS_SPAM_ERROR: $dbw->rollback(); $result['error'] = wfMsg('spamprotectiontext') . '<p>( Case #8 )</p>'; break; default: $dbw->rollback(); $result['error'] = wfMsg('categoryselect-edit-abort'); } } else { $result['error'] = wfMsg('categoryselect-error-user-rights'); } } } wfProfileOut(__METHOD__); return json_encode($result); }
/** * This is the meaty bit -- restores archived revisions of the given page * to the cur/old tables. If the page currently exists, all revisions will * be stuffed into old, otherwise the most recent will go into cur. * * @param array $timestamps Pass an empty array to restore all revisions, otherwise list the ones to undelete. * @param string $comment * @param array $fileVersions * * @return int number of revisions restored */ private function undeleteRevisions($timestamps) { global $wgParser, $wgDBtype; $restoreAll = empty($timestamps); $dbw =& wfGetDB(DB_MASTER); extract($dbw->tableNames('page', 'archive')); # Does this page already exist? We'll have to update it... $article = new Article($this->title); $options = $wgDBtype == 'postgres' ? '' : 'FOR UPDATE'; $page = $dbw->selectRow('page', array('page_id', 'page_latest'), array('page_namespace' => $this->title->getNamespace(), 'page_title' => $this->title->getDBkey()), __METHOD__, $options); if ($page) { # Page already exists. Import the history, and if necessary # we'll update the latest revision field in the record. $newid = 0; $pageId = $page->page_id; $previousRevId = $page->page_latest; } else { # Have to create a new article... $newid = $article->insertOn($dbw); $pageId = $newid; $previousRevId = 0; } if ($restoreAll) { $oldones = '1 = 1'; # All revisions... } else { $oldts = implode(',', array_map(array(&$dbw, 'addQuotes'), array_map(array(&$dbw, 'timestamp'), $timestamps))); $oldones = "ar_timestamp IN ( {$oldts} )"; } /** * Restore each revision... */ $result = $dbw->select('archive', array('ar_rev_id', 'ar_text', 'ar_comment', 'ar_user', 'ar_user_text', 'ar_timestamp', 'ar_minor_edit', 'ar_flags', 'ar_text_id'), array('ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), $oldones), __METHOD__, array('ORDER BY' => 'ar_timestamp')); if ($dbw->numRows($result) < count($timestamps)) { wfDebug(__METHOD__ . ": couldn't find all requested rows\n"); return false; } $revision = null; $newRevId = $previousRevId; $restored = 0; while ($row = $dbw->fetchObject($result)) { if ($row->ar_text_id) { // Revision was deleted in 1.5+; text is in // the regular text table, use the reference. // Specify null here so the so the text is // dereferenced for page length info if needed. $revText = null; } else { // Revision was deleted in 1.4 or earlier. // Text is squashed into the archive row, and // a new text table entry will be created for it. $revText = Revision::getRevisionText($row, 'ar_'); } $revision = new Revision(array('page' => $pageId, 'id' => $row->ar_rev_id, 'text' => $revText, 'comment' => $row->ar_comment, 'user' => $row->ar_user, 'user_text' => $row->ar_user_text, 'timestamp' => $row->ar_timestamp, 'minor_edit' => $row->ar_minor_edit, 'text_id' => $row->ar_text_id)); $newRevId = $revision->insertOn($dbw); $restored++; } if ($revision) { # FIXME: Update latest if newer as well... if ($newid) { // Attach the latest revision to the page... $article->updateRevisionOn($dbw, $revision, $previousRevId); // Update site stats, link tables, etc $article->createUpdates($revision); } if ($newid) { Article::onArticleCreate($this->title); } else { Article::onArticleEdit($this->title); } } else { # Something went terribly wrong! } # Now that it's safely stored, take it out of the archive $dbw->delete('archive', array('ar_namespace' => $this->title->getNamespace(), 'ar_title' => $this->title->getDBkey(), $oldones), __METHOD__); return $restored; }
function onEdit(&$mvd_pages_cache, $mvd_id) { // force update local mvd_page_cache from db: $mvd_pages_cache[$mvd_id] = MV_Index::getMVDbyId($mvd_id); $stream_name = MV_Stream::getStreamNameFromId($this->mvd_pages[$mvd_id]->stream_id); $streamTitle = Title::newFromText($stream_name, MV_NS_STREAM); // clear the cache for the parent stream page: // print "clear parent stream: " . $streamTitle ."\n"; Article::onArticleEdit($streamTitle); }
function importOldRevision() { $fname = "WikiImporter::importOldRevision"; $dbw =& wfGetDB(DB_MASTER); # Sneak a single revision into place $user = User::newFromName($this->getUser()); if ($user) { $userId = intval($user->getId()); $userText = $user->getName(); } else { $userId = 0; $userText = $this->getUser(); } // avoid memory leak...? $linkCache =& LinkCache::singleton(); $linkCache->clear(); $article = new Article($this->title); $pageId = $article->getId(); if ($pageId == 0) { # must create the page... $pageId = $article->insertOn($dbw); $created = true; } else { $created = false; } # FIXME: Check for exact conflicts # FIXME: Use original rev_id optionally # FIXME: blah blah blah #if( $numrows > 0 ) { # return wfMsg( "importhistoryconflict" ); #} # Insert the row $revision = new Revision(array('page' => $pageId, 'text' => $this->getText(), 'comment' => $this->getComment(), 'user' => $userId, 'user_text' => $userText, 'timestamp' => $this->timestamp, 'minor_edit' => $this->minor)); $revId = $revision->insertOn($dbw); $changed = $article->updateIfNewerOn($dbw, $revision); if ($created) { wfDebug(__METHOD__ . ": running onArticleCreate\n"); Article::onArticleCreate($this->title); } else { if ($changed) { wfDebug(__METHOD__ . ": running onArticleEdit\n"); Article::onArticleEdit($this->title); } } if ($created || $changed) { wfDebug(__METHOD__ . ": running edit updates\n"); $article->editUpdates($this->getText(), $this->getComment(), $this->minor, $this->timestamp, $revId); } return true; }
function FrontBackForcedArticleSaveCompleteHook(&$article, &$user, $text, $summary, $minoredit, $watchthis, $sectionanchor, &$flags, $revision, &$status, $baseRevId) { global $wgLang; $frontMsg = wfMsgForContent('frontbackforced-front'); $backMsg = wfMsgForContent('frontbackforced-back'); $forcedMsg = wfMsgForContent('frontbackforced-forced'); $myTitle = $article->getTitle()->getPrefixedDBkey(); if (substr($myTitle, strlen($myTitle) - strlen($frontMsg), strlen($frontMsg)) == $frontMsg) { $frontBaseTitle = Title::newFromDBkey(substr($myTitle, 0, strlen($myTitle) - strlen($frontMsg))); $frontBaseTitle->invalidateCache(); Article::onArticleCreate($frontBaseTitle); Article::onArticleEdit($frontBaseTitle); } if (substr($myTitle, strlen($myTitle) - strlen($backMsg), strlen($backMsg)) == $backMsg) { $backBaseTitle = Title::newFromDBkey(substr($myTitle, 0, strlen($myTitle) - strlen($backMsg))); $backBaseTitle->invalidateCache(); Article::onArticleCreate($backBaseTitle); Article::onArticleEdit($backBaseTitle); } if (substr($myTitle, strlen($myTitle) - strlen($forcedMsg), strlen($forcedMsg)) == $forcedMsg) { $forcedBaseTitle = Title::newFromDBkey(substr($myTitle, 0, strlen($myTitle) - strlen($forcedMsg))); $forcedBaseTitle->invalidateCache(); Article::onArticleCreate($forcedBaseTitle); Article::onArticleEdit($forcedBaseTitle); } return true; }