Example #1
0
    }
    $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++;
}
// 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);
}
Example #2
0
 /**
  * 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;
 }
Example #3
0
 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;
 }
 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;
 }
 /**
  * Duplicate one page to another, including full histories
  * Does some basic error-catching, but not as much as the code above [should]
  *
  * @param $source Title to duplicate
  * @param $dest Title to save to
  * @return bool
  */
 private function duplicate(&$source, &$dest)
 {
     global $wgUser, $wgBot;
     if (!$source->exists() || $dest->exists()) {
         return false;
     }
     # Source doesn't exist, or destination does
     $dbw = wfGetDB(DB_MASTER);
     $dbw->begin();
     $sid = $source->getArticleId();
     # Create an article representing the destination page and save it
     $destArticle = new Article($dest);
     $aid = $destArticle->insertOn($dbw);
     # Perform the revision duplication
     # An INSERT...SELECT here seems to f**k things up
     $res = $dbw->select('revision', '*', array('rev_page' => $sid), __METHOD__);
     if ($res && $dbw->numRows($res) > 0) {
         while ($row = $dbw->fetchObject($res)) {
             $values['rev_page'] = $aid;
             $values['rev_text_id'] = $row->rev_text_id;
             $values['rev_comment'] = $row->rev_comment;
             $values['rev_user'] = $row->rev_user;
             $values['rev_user_text'] = $row->rev_user_text;
             $values['rev_timestamp'] = $row->rev_timestamp;
             $values['rev_minor_edit'] = $row->rev_minor_edit;
             $values['rev_deleted'] = $row->rev_deleted;
             $dbw->insert('revision', $values, __METHOD__);
         }
         $dbw->freeResult($res);
     }
     # Update page record
     $latest = $dbw->selectField('revision', 'MAX(rev_id)', array('rev_page' => $aid), __METHOD__);
     $rev = Revision::newFromId($latest);
     $destArticle->updateRevisionOn($dbw, $rev);
     # Commit transaction
     $dbw->commit();
     # Create a null revision with an explanation; do cache clearances, etc.
     $dbw->begin();
     $comment = wfMsgForContent('duplicator-summary', $source->getPrefixedText());
     $nr = Revision::newNullRevision($dbw, $aid, $comment, true);
     $nid = $nr->insertOn($dbw);
     $destArticle->updateRevisionOn($dbw, $nr);
     $destArticle->createUpdates($nr);
     Article::onArticleCreate($dest);
     $bot = $wgUser->isAllowed('bot');
     RecentChange::notifyNew($nr->getTimestamp(), $dest, true, $wgUser, $comment, $bot);
     $dest->invalidateCache();
     $dbw->commit();
     return true;
 }
Example #7
0
 /**
  * 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;
 }