/** * Insert a new revision into the database, returning the new revision ID * number on success and dies horribly on failure. * * @param Database $dbw * @return int */ public function insertOn($dbw) { global $wgDefaultExternalStore; wfProfileIn(__METHOD__); $data = $this->mText; $flags = Revision::compressRevisionText($data); # Write to external storage if required if ($wgDefaultExternalStore) { // Store and get the URL $data = ExternalStore::insertToDefault($data); if (!$data) { throw new MWException("Unable to store text to external storage"); } if ($flags) { $flags .= ','; } $flags .= 'external'; } # Record the text (or external storage URL) to the text table if (!isset($this->mTextId)) { $old_id = $dbw->nextSequenceValue('text_old_id_val'); $dbw->insert('text', array('old_id' => $old_id, 'old_text' => $data, 'old_flags' => $flags), __METHOD__); $this->mTextId = $dbw->insertId(); } # Record the edit in revisions $rev_id = isset($this->mId) ? $this->mId : $dbw->nextSequenceValue('rev_rev_id_val'); $dbw->insert('revision', array('rev_id' => $rev_id, 'rev_page' => $this->mPage, 'rev_text_id' => $this->mTextId, 'rev_comment' => $this->mComment, 'rev_minor_edit' => $this->mMinorEdit ? 1 : 0, 'rev_user' => $this->mUser, 'rev_user_text' => $this->mUserText, 'rev_timestamp' => $dbw->timestamp($this->mTimestamp), 'rev_deleted' => $this->mDeleted, 'rev_len' => $this->mSize, 'rev_parent_id' => is_null($this->mParentId) ? $this->getPreviousRevisionId($dbw) : $this->mParentId), __METHOD__); $this->mId = !is_null($rev_id) ? $rev_id : $dbw->insertId(); wfRunHooks('RevisionInsertComplete', array(&$this, $data, $flags)); wfProfileOut(__METHOD__); return $this->mId; }
/** * Insert a new revision into the database, returning the new revision ID * number on success and dies horribly on failure. * * @param Database $dbw * @return int */ function insertOn(&$dbw) { global $wgDefaultExternalStore; $fname = 'Revision::insertOn'; wfProfileIn($fname); $data = $this->mText; $flags = Revision::compressRevisionText($data); # Write to external storage if required if ($wgDefaultExternalStore) { if (is_array($wgDefaultExternalStore)) { // Distribute storage across multiple clusters $store = $wgDefaultExternalStore[mt_rand(0, count($wgDefaultExternalStore) - 1)]; } else { $store = $wgDefaultExternalStore; } require_once 'ExternalStore.php'; // Store and get the URL $data = ExternalStore::insert($store, $data); if (!$data) { # This should only happen in the case of a configuration error, where the external store is not valid throw new MWException("Unable to store text to external storage {$store}"); } if ($flags) { $flags .= ','; } $flags .= 'external'; } # Record the text (or external storage URL) to the text table if (!isset($this->mTextId)) { $old_id = $dbw->nextSequenceValue('text_old_id_val'); $dbw->insert('text', array('old_id' => $old_id, 'old_text' => $data, 'old_flags' => $flags), $fname); $this->mTextId = $dbw->insertId(); } # Record the edit in revisions $rev_id = isset($this->mId) ? $this->mId : $dbw->nextSequenceValue('rev_rev_id_val'); $dbw->insert('revision', array('rev_id' => $rev_id, 'rev_page' => $this->mPage, 'rev_text_id' => $this->mTextId, 'rev_comment' => $this->mComment, 'rev_minor_edit' => $this->mMinorEdit ? 1 : 0, 'rev_user' => $this->mUser, 'rev_user_text' => $this->mUserText, 'rev_timestamp' => $dbw->timestamp($this->mTimestamp), 'rev_deleted' => $this->mDeleted), $fname); $this->mId = !is_null($rev_id) ? $rev_id : $dbw->insertId(); wfProfileOut($fname); return $this->mId; }
function testCompressRevisionTextUtf8Gzip() { global $wgCompressRevisions; $wgCompressRevisions = true; $row = new stdClass(); $row->old_text = "Wiki est l'école superieur !"; $row->old_flags = Revision::compressRevisionText($row->old_text); $this->assertTrue(false !== strpos($row->old_flags, 'utf-8'), "Flags should contain 'utf-8'"); $this->assertTrue(false !== strpos($row->old_flags, 'gzip'), "Flags should contain 'gzip'"); $this->assertEquals("Wiki est l'école superieur !", gzinflate($row->old_text), "Direct check"); $this->assertEquals("Wiki est l'école superieur !", Revision::getRevisionText($row), "getRevisionText"); }
function importRevision(&$revision, &$importer) { $id = $revision->getID(); $content = $revision->getContent(Revision::RAW); $id = $id ? $id : ''; if ($content === null) { echo "Revision {$id} is broken, we have no content available\n"; return; } $text = $content->serialize(); if ($text === '') { // This is what happens if the revision was broken at the time the // dump was made. Unfortunately, it also happens if the revision was // legitimately blank, so there's no way to tell the difference. To // be safe, we'll skip it and leave it broken echo "Revision {$id} is blank in the dump, may have been broken before export\n"; return; } if (!$id) { // No ID, can't import echo "No id tag in revision, can't import\n"; return; } // Find text row again $dbr = wfGetDB(DB_SLAVE); $oldId = $dbr->selectField('revision', 'rev_text_id', ['rev_id' => $id], __METHOD__); if (!$oldId) { echo "Missing revision row for rev_id {$id}\n"; return; } // Compress the text $flags = Revision::compressRevisionText($text); // Update the text row $dbw = wfGetDB(DB_MASTER); $dbw->update('text', ['old_flags' => $flags, 'old_text' => $text], ['old_id' => $oldId], __METHOD__, ['LIMIT' => 1]); // Remove it from the unfixed list and add it to the fixed list unset($this->errors['restore text'][$id]); $this->errors['fixed'][$id] = true; }
function importRevision(&$revision, &$importer) { $fname = 'CheckStorage::importRevision'; $id = $revision->getID(); $text = $revision->getText(); if ($text === '') { // This is what happens if the revision was broken at the time the // dump was made. Unfortunately, it also happens if the revision was // legitimately blank, so there's no way to tell the difference. To // be safe, we'll skip it and leave it broken $id = $id ? $id : ''; echo "Revision {$id} is blank in the dump, may have been broken before export\n"; return; } if (!$id) { // No ID, can't import echo "No id tag in revision, can't import\n"; return; } // Find text row again $dbr =& wfGetDB(DB_SLAVE); $oldId = $dbr->selectField('revision', 'rev_text_id', array('rev_id' => $id), $fname); if (!$oldId) { echo "Missing revision row for rev_id {$id}\n"; return; } // Compress the text $flags = Revision::compressRevisionText($text); // Update the text row $dbw->update('text', array('old_flags' => $flags, 'old_text' => $text), array('old_id' => $oldId), $fname, array('LIMIT' => 1)); // Remove it from the unfixed list and add it to the fixed list unset($this->errors['restore text'][$id]); $this->errors['fixed'][$id] = true; }
function testCompressRevisionTextLatin1Gzip() { $GLOBALS['wgCompressRevisions'] = true; $GLOBALS['wgUseLatin1'] = true; $row = new stdClass(); $row->old_text = "Wiki est l'école superieur !"; $row->old_flags = Revision::compressRevisionText($row->old_text); $this->assertFalse(false !== strpos($row->old_flags, 'utf-8'), "Flags should not contain 'utf-8'"); $this->assertTrue(false !== strpos($row->old_flags, 'gzip'), "Flags should contain 'gzip'"); $this->assertEquals("Wiki est l'école superieur !", gzinflate($row->old_text), "Direct check"); $this->assertEquals("Wiki est l'école superieur !", Revision::getRevisionText($row), "getRevisionText"); }
/** * Set diff cache (for import operations) * @param $codeRev CodeRevision */ public function setDiffCache(CodeRevision $codeRev) { global $wgMemc; wfProfileIn(__METHOD__); $rev1 = $codeRev->getId() - 1; $rev2 = $codeRev->getId(); $svn = SubversionAdaptor::newFromRepo($this->path); $data = $svn->getDiff('', $rev1, $rev2); // Store to cache $key = wfMemcKey('svn', md5($this->path), 'diff', $rev1, $rev2); $wgMemc->set($key, $data, 3600 * 24 * 3); // Permanent DB storage $storedData = $data; $flags = Revision::compressRevisionText($storedData); $dbw = wfGetDB(DB_MASTER); $dbw->update('code_rev', array('cr_diff' => $storedData, 'cr_flags' => $flags), array('cr_repo_id' => $this->id, 'cr_id' => $codeRev->getId()), __METHOD__); wfProfileOut(__METHOD__); }
function insert_text() { global $wgDefaultExternalStore, $IP; $inset_text = "<!-- " . md5($this->p_wiki_hidden) . " -->" . $this->text_to_save; $flags = Revision::compressRevisionText($inset_text); if ($wgDefaultExternalStore) { $flags .= 'external'; } $bs = $this->wDB->nextSequenceValue('text_old_id_seq'); $this->wDB->insert('text', array('old_text' => $inset_text, 'old_flags' => $flags)); $this->insert_textID = $this->wDB->insertId(); }
/** * Should only be used for setting the initial content. To set subsequent content * use self::setNextContent * * @param string $content * @param string $format wikitext|html * @param Title|null $title When null the related workflow will be lazy-loaded to locate the title * @throws DataModelException */ protected function setContent($content, $format, Title $title = null) { if ($this->moderationState !== self::MODERATED_NONE) { throw new DataModelException('TODO: Cannot change content of restricted revision', 'process-data'); } if ($this->content !== null) { throw new DataModelException('Updating content must use setNextContent method', 'process-data'); } if (!$title) { $title = $this->getCollection()->getTitle(); } // never trust incoming html - roundtrip to wikitext first if ($format !== 'wikitext') { $content = Utils::convert($format, 'wikitext', $content, $title); $format = 'wikitext'; } // Run pre-save transform $content = ContentHandler::makeContent($content, $title, CONTENT_MODEL_WIKITEXT)->preSaveTransform($title, $this->getUser(), WikiPage::factory($title)->makeParserOptions($this->getUser()))->serialize('text/x-wiki'); // Keep consistent with normal edit page, trim only trailing whitespaces $content = rtrim($content); $this->convertedContent = array($format => $content); // convert content to desired storage format $storageFormat = $this->getStorageFormat(); if ($this->isFormatted() && $storageFormat !== $format) { $this->convertedContent[$storageFormat] = Utils::convert($format, $storageFormat, $content, $title); } $this->content = $this->decompressedContent = $this->convertedContent[$storageFormat]; $this->contentUrl = null; // should this only remove a subset of flags? $this->flags = array_filter(explode(',', \Revision::compressRevisionText($this->content))); $this->flags[] = $storageFormat; $this->contentLength = mb_strlen($this->getContent('wikitext')); }
/** * Insert a new revision into the database, returning the new revision ID * number on success and dies horribly on failure. * * @param Database $dbw * @return int */ function insertOn(&$dbw) { $fname = 'Revision::insertOn'; wfProfileIn($fname); $mungedText = $this->mText; $flags = Revision::compressRevisionText($mungedText); # Record the text to the text table if (!isset($this->mTextId)) { $old_id = $dbw->nextSequenceValue('text_old_id_val'); $dbw->insert('text', array('old_id' => $old_id, 'old_text' => $mungedText, 'old_flags' => $flags), $fname); $this->mTextId = $dbw->insertId(); } # Record the edit in revisions $rev_id = isset($this->mId) ? $this->mId : $dbw->nextSequenceValue('rev_rev_id_val'); $dbw->insert('revision', array('rev_id' => $rev_id, 'rev_page' => $this->mPage, 'rev_text_id' => $this->mTextId, 'rev_comment' => $this->mComment, 'rev_minor_edit' => $this->mMinorEdit ? 1 : 0, 'rev_user' => $this->mUser, 'rev_user_text' => $this->mUserText, 'rev_timestamp' => $dbw->timestamp($this->mTimestamp), 'rev_deleted' => $this->mDeleted), $fname); $this->mId = $dbw->insertId(); wfProfileOut($fname); return $this->mId; }