protected function populatePage(DatabaseBase $dbw, $ns)
 {
     $toSave = array();
     $lastId = 0;
     $nsCondition = $ns === 'all' ? array() : array('page_namespace' => $ns);
     do {
         $rows = $dbw->select('page', array('page_namespace', 'page_title', 'page_id'), array('page_content_model' => null, 'page_id > ' . $dbw->addQuotes($lastId)) + $nsCondition, __METHOD__, array('LIMIT' => $this->mBatchSize, 'ORDER BY' => 'page_id ASC'));
         $this->output("Fetched {$rows->numRows()} rows.\n");
         foreach ($rows as $row) {
             $title = Title::newFromRow($row);
             $model = ContentHandler::getDefaultModelFor($title);
             $toSave[$model][] = $row->page_id;
             if (count($toSave[$model]) >= $this->mBatchSize) {
                 $this->updatePageRows($dbw, $toSave[$model], $model);
                 unset($toSave[$model]);
             }
             $lastId = $row->page_id;
         }
     } while ($rows->numRows() >= $this->mBatchSize);
     foreach ($toSave as $model => $pages) {
         $this->updatePageRows($dbw, $pages, $model);
     }
 }
예제 #2
0
 /**
  * Get the page's content model id, see the CONTENT_MODEL_XXX constants.
  *
  * @param int $flags A bit field; may be Title::GAID_FOR_UPDATE to select for update
  * @return string Content model id
  */
 public function getContentModel($flags = 0)
 {
     if (!$this->mContentModel && $this->getArticleID($flags)) {
         $linkCache = LinkCache::singleton();
         $linkCache->addLinkObj($this);
         # in case we already had an article ID
         $this->mContentModel = $linkCache->getGoodLinkFieldObj($this, 'model');
     }
     if (!$this->mContentModel) {
         $this->mContentModel = ContentHandler::getDefaultModelFor($this);
     }
     return $this->mContentModel;
 }
예제 #3
0
 /**
  * Dumps a "<revision>" section on the output stream, with
  * data filled in from the given database row.
  *
  * @param object $row
  * @return string
  * @access private
  */
 function writeRevision($row)
 {
     wfProfileIn(__METHOD__);
     $out = "    <revision>\n";
     $out .= "      " . Xml::element('id', null, strval($row->rev_id)) . "\n";
     if (isset($row->rev_parent_id) && $row->rev_parent_id) {
         $out .= "      " . Xml::element('parentid', null, strval($row->rev_parent_id)) . "\n";
     }
     $out .= $this->writeTimestamp($row->rev_timestamp);
     if (isset($row->rev_deleted) && $row->rev_deleted & Revision::DELETED_USER) {
         $out .= "      " . Xml::element('contributor', array('deleted' => 'deleted')) . "\n";
     } else {
         $out .= $this->writeContributor($row->rev_user, $row->rev_user_text);
     }
     if (isset($row->rev_minor_edit) && $row->rev_minor_edit) {
         $out .= "      <minor/>\n";
     }
     if (isset($row->rev_deleted) && $row->rev_deleted & Revision::DELETED_COMMENT) {
         $out .= "      " . Xml::element('comment', array('deleted' => 'deleted')) . "\n";
     } elseif ($row->rev_comment != '') {
         $out .= "      " . Xml::elementClean('comment', array(), strval($row->rev_comment)) . "\n";
     }
     if (isset($row->rev_content_model) && !is_null($row->rev_content_model)) {
         $content_model = strval($row->rev_content_model);
     } else {
         // probably using $wgContentHandlerUseDB = false;
         $title = Title::makeTitle($row->page_namespace, $row->page_title);
         $content_model = ContentHandler::getDefaultModelFor($title);
     }
     $content_handler = ContentHandler::getForModelID($content_model);
     if (isset($row->rev_content_format) && !is_null($row->rev_content_format)) {
         $content_format = strval($row->rev_content_format);
     } else {
         // probably using $wgContentHandlerUseDB = false;
         $content_format = $content_handler->getDefaultFormat();
     }
     $text = '';
     if (isset($row->rev_deleted) && $row->rev_deleted & Revision::DELETED_TEXT) {
         $out .= "      " . Xml::element('text', array('deleted' => 'deleted')) . "\n";
     } elseif (isset($row->old_text)) {
         // Raw text from the database may have invalid chars
         $text = strval(Revision::getRevisionText($row));
         $text = $content_handler->exportTransform($text, $content_format);
         $out .= "      " . Xml::elementClean('text', array('xml:space' => 'preserve', 'bytes' => intval($row->rev_len)), strval($text)) . "\n";
     } else {
         // Stub output
         $out .= "      " . Xml::element('text', array('id' => $row->rev_text_id, 'bytes' => intval($row->rev_len)), "") . "\n";
     }
     if (isset($row->rev_sha1) && $row->rev_sha1 && !($row->rev_deleted & Revision::DELETED_TEXT)) {
         $out .= "      " . Xml::element('sha1', null, strval($row->rev_sha1)) . "\n";
     } else {
         $out .= "      <sha1/>\n";
     }
     $out .= "      " . Xml::element('model', null, strval($content_model)) . "\n";
     $out .= "      " . Xml::element('format', null, strval($content_format)) . "\n";
     wfRunHooks('XmlDumpWriterWriteRevision', array(&$this, &$out, $row, $text));
     $out .= "    </revision>\n";
     wfProfileOut(__METHOD__);
     return $out;
 }
예제 #4
0
 /**
  * @dataProvider dataGetDefaultModelFor
  */
 public function testGetDefaultModelFor($title, $expectedModelId)
 {
     $title = Title::newFromText($title);
     $this->assertEquals($expectedModelId, ContentHandler::getDefaultModelFor($title));
 }
예제 #5
0
 /**
  * Get the page's content model id, see the CONTENT_MODEL_XXX constants.
  *
  * @throws MWException
  * @param int $flags A bit field; may be Title::GAID_FOR_UPDATE to select for update
  * @return string Content model id
  */
 public function getContentModel($flags = 0)
 {
     # Calling getArticleID() loads the field from cache as needed
     if (!$this->mContentModel && $this->getArticleID($flags)) {
         $linkCache = LinkCache::singleton();
         $this->mContentModel = $linkCache->getGoodLinkFieldObj($this, 'model');
     }
     if (!$this->mContentModel) {
         $this->mContentModel = ContentHandler::getDefaultModelFor($this);
     }
     if (!$this->mContentModel) {
         throw new MWException('Failed to determine content model!');
     }
     return $this->mContentModel;
 }
예제 #6
0
 protected function checkContentModel()
 {
     global $wgContentHandlerUseDB;
     $title = $this->getTitle();
     //note: may return null for revisions that have not yet been inserted.
     $model = $this->getContentModel();
     $format = $this->getContentFormat();
     $handler = $this->getContentHandler();
     if (!$handler->isSupportedFormat($format)) {
         $t = $title->getPrefixedDBkey();
         throw new MWException("Can't use format {$format} with content model {$model} on {$t}");
     }
     if (!$wgContentHandlerUseDB && $title) {
         // if $wgContentHandlerUseDB is not set, all revisions must use the default content model and format.
         $defaultModel = ContentHandler::getDefaultModelFor($title);
         $defaultHandler = ContentHandler::getForModelID($defaultModel);
         $defaultFormat = $defaultHandler->getDefaultFormat();
         if ($this->getContentModel() != $defaultModel) {
             $t = $title->getPrefixedDBkey();
             throw new MWException("Can't save non-default content model with \$wgContentHandlerUseDB disabled: " . "model is {$model} , default for {$t} is {$defaultModel}");
         }
         if ($this->getContentFormat() != $defaultFormat) {
             $t = $title->getPrefixedDBkey();
             throw new MWException("Can't use non-default content format with \$wgContentHandlerUseDB disabled: " . "format is {$format}, default for {$t} is {$defaultFormat}");
         }
     }
     $content = $this->getContent(Revision::RAW);
     if (!$content || !$content->isValid()) {
         $t = $title->getPrefixedDBkey();
         throw new MWException("Content of {$t} is not valid! Content model is {$model}");
     }
 }
 /**
  * @dataProvider provideIsCountable
  * @covers WikiPage::isCountable
  */
 public function testIsCountable($title, $model, $text, $mode, $expected)
 {
     global $wgContentHandlerUseDB;
     $this->setMwGlobals('wgArticleCountMethod', $mode);
     $title = Title::newFromText($title);
     if (!$wgContentHandlerUseDB && $model && ContentHandler::getDefaultModelFor($title) != $model) {
         $this->markTestSkipped("Can not use non-default content model {$model} for " . $title->getPrefixedDBkey() . " with \$wgContentHandlerUseDB disabled.");
     }
     $page = $this->createPage($title, $text, $model);
     $editInfo = $page->prepareContentForEdit($page->getContent());
     $v = $page->isCountable();
     $w = $page->isCountable($editInfo);
     $this->assertEquals($expected, $v, "isCountable( null ) returned unexpected value " . var_export($v, true) . " instead of " . var_export($expected, true) . " in mode `{$mode}` for text \"{$text}\"");
     $this->assertEquals($expected, $w, "isCountable( \$editInfo ) returned unexpected value " . var_export($v, true) . " instead of " . var_export($expected, true) . " in mode `{$mode}` for text \"{$text}\"");
 }
예제 #8
0
 /**
  * Move page to a title which is either a redirect to the
  * source page or nonexistent
  *
  * @fixme This was basically directly moved from Title, it should be split into smaller functions
  * @param User $user the User doing the move
  * @param Title $nt The page to move to, which should be a redirect or nonexistent
  * @param string $reason The reason for the move
  * @param bool $createRedirect Whether to leave a redirect at the old title. Does not check
  *   if the user has the suppressredirect right
  * @throws MWException
  */
 private function moveToInternal(User $user, &$nt, $reason = '', $createRedirect = true)
 {
     global $wgContLang;
     if ($nt->exists()) {
         $moveOverRedirect = true;
         $logType = 'move_redir';
     } else {
         $moveOverRedirect = false;
         $logType = 'move';
     }
     if ($createRedirect) {
         if ($this->oldTitle->getNamespace() == NS_CATEGORY && !wfMessage('category-move-redirect-override')->inContentLanguage()->isDisabled()) {
             $redirectContent = new WikitextContent(wfMessage('category-move-redirect-override')->params($nt->getPrefixedText())->inContentLanguage()->plain());
         } else {
             $contentHandler = ContentHandler::getForTitle($this->oldTitle);
             $redirectContent = $contentHandler->makeRedirectContent($nt, wfMessage('move-redirect-text')->inContentLanguage()->plain());
         }
         // NOTE: If this page's content model does not support redirects, $redirectContent will be null.
     } else {
         $redirectContent = null;
     }
     // Figure out whether the content model is no longer the default
     $oldDefault = ContentHandler::getDefaultModelFor($this->oldTitle);
     $contentModel = $this->oldTitle->getContentModel();
     $newDefault = ContentHandler::getDefaultModelFor($nt);
     $defaultContentModelChanging = $oldDefault !== $newDefault && $oldDefault === $contentModel;
     // bug 57084: log_page should be the ID of the *moved* page
     $oldid = $this->oldTitle->getArticleID();
     $logTitle = clone $this->oldTitle;
     $logEntry = new ManualLogEntry('move', $logType);
     $logEntry->setPerformer($user);
     $logEntry->setTarget($logTitle);
     $logEntry->setComment($reason);
     $logEntry->setParameters(array('4::target' => $nt->getPrefixedText(), '5::noredir' => $redirectContent ? '0' : '1'));
     $formatter = LogFormatter::newFromEntry($logEntry);
     $formatter->setContext(RequestContext::newExtraneousContext($this->oldTitle));
     $comment = $formatter->getPlainActionText();
     if ($reason) {
         $comment .= wfMessage('colon-separator')->inContentLanguage()->text() . $reason;
     }
     # Truncate for whole multibyte characters.
     $comment = $wgContLang->truncate($comment, 255);
     $dbw = wfGetDB(DB_MASTER);
     $oldpage = WikiPage::factory($this->oldTitle);
     $oldcountable = $oldpage->isCountable();
     $newpage = WikiPage::factory($nt);
     if ($moveOverRedirect) {
         $newid = $nt->getArticleID();
         $newcontent = $newpage->getContent();
         # Delete the old redirect. We don't save it to history since
         # by definition if we've got here it's rather uninteresting.
         # We have to remove it so that the next step doesn't trigger
         # a conflict on the unique namespace+title index...
         $dbw->delete('page', array('page_id' => $newid), __METHOD__);
         $newpage->doDeleteUpdates($newid, $newcontent);
     }
     # Save a null revision in the page's history notifying of the move
     $nullRevision = Revision::newNullRevision($dbw, $oldid, $comment, true, $user);
     if (!is_object($nullRevision)) {
         throw new MWException('No valid null revision produced in ' . __METHOD__);
     }
     $nullRevision->insertOn($dbw);
     # Change the name of the target page:
     $dbw->update('page', array('page_namespace' => $nt->getNamespace(), 'page_title' => $nt->getDBkey()), array('page_id' => $oldid), __METHOD__);
     // clean up the old title before reset article id - bug 45348
     if (!$redirectContent) {
         WikiPage::onArticleDelete($this->oldTitle);
     }
     $this->oldTitle->resetArticleID(0);
     // 0 == non existing
     $nt->resetArticleID($oldid);
     $newpage->loadPageData(WikiPage::READ_LOCKING);
     // bug 46397
     $newpage->updateRevisionOn($dbw, $nullRevision);
     Hooks::run('NewRevisionFromEditComplete', array($newpage, $nullRevision, $nullRevision->getParentId(), $user));
     $newpage->doEditUpdates($nullRevision, $user, array('changed' => false, 'moved' => true, 'oldcountable' => $oldcountable));
     // If the default content model changes, we need to populate rev_content_model
     if ($defaultContentModelChanging) {
         $dbw->update('revision', array('rev_content_model' => $contentModel), array('rev_page' => $nt->getArticleID(), 'rev_content_model IS NULL'), __METHOD__);
     }
     if (!$moveOverRedirect) {
         WikiPage::onArticleCreate($nt);
     }
     # Recreate the redirect, this time in the other direction.
     if ($redirectContent) {
         $redirectArticle = WikiPage::factory($this->oldTitle);
         $redirectArticle->loadFromRow(false, WikiPage::READ_LOCKING);
         // bug 46397
         $newid = $redirectArticle->insertOn($dbw);
         if ($newid) {
             // sanity
             $this->oldTitle->resetArticleID($newid);
             $redirectRevision = new Revision(array('title' => $this->oldTitle, 'page' => $newid, 'user_text' => $user->getName(), 'user' => $user->getId(), 'comment' => $comment, 'content' => $redirectContent));
             $redirectRevision->insertOn($dbw);
             $redirectArticle->updateRevisionOn($dbw, $redirectRevision, 0);
             Hooks::run('NewRevisionFromEditComplete', array($redirectArticle, $redirectRevision, false, $user));
             $redirectArticle->doEditUpdates($redirectRevision, $user, array('created' => true));
         }
     }
     # Log the move
     $logid = $logEntry->insert();
     $logEntry->publish($logid);
 }
예제 #9
0
 /**
  * Get the page's content model id, see the CONTENT_MODEL_XXX constants.
  *
  * @throws MWException
  * @return String: Content model id
  */
 public function getContentModel()
 {
     if (!$this->mContentModel) {
         $linkCache = LinkCache::singleton();
         $this->mContentModel = $linkCache->getGoodLinkFieldObj($this, 'model');
     }
     if (!$this->mContentModel) {
         $this->mContentModel = ContentHandler::getDefaultModelFor($this);
     }
     if (!$this->mContentModel) {
         throw new MWException('Failed to determine content model!');
     }
     return $this->mContentModel;
 }