예제 #1
0
 /**
  * @since 2.2
  */
 public function getEditInfo(Title $title)
 {
     $this->page = new \WikiPage($title);
     if (class_exists('WikitextContent')) {
         $content = $this->page->getRevision()->getContent();
         $format = $content->getContentHandler()->getDefaultFormat();
         return $this->page->prepareContentForEdit($content, null, null, $format);
     }
     return $this->page->prepareTextForEdit($this->page->getRevision()->getRawText(), null, null);
 }
예제 #2
0
 /**
  * @param WikiPage $page
  * @param ParserOptions $parserOptions ParserOptions to use for the parse
  * @param int $revid ID of the revision being parsed.
  * @param bool $useParserCache Whether to use the parser cache.
  *   operation.
  * @param Content|string $content Content to parse or null to load it; may
  *   also be given as a wikitext string, for BC.
  */
 public function __construct(WikiPage $page, ParserOptions $parserOptions, $revid, $useParserCache, $content = null)
 {
     if (is_string($content)) {
         // BC: old style call
         $modelId = $page->getRevision()->getContentModel();
         $format = $page->getRevision()->getContentFormat();
         $content = ContentHandler::makeContent($content, $page->getTitle(), $modelId, $format);
     }
     $this->page = $page;
     $this->revid = $revid;
     $this->cacheable = $useParserCache;
     $this->parserOptions = $parserOptions;
     $this->content = $content;
     $this->cacheKey = ParserCache::singleton()->getKey($page, $parserOptions);
     $keyPrefix = $this->cacheKey ?: wfMemcKey('articleview', 'missingcachekey');
     parent::__construct('ArticleView', $keyPrefix . ':revid:' . $revid);
 }
 static function onPageContentSave(WikiPage &$wikiPage, User &$user, Content &$content, &$summary, $isMinor, $isWatch, $section, &$flags, Status &$status)
 {
     // get the current tags from the page
     /////////////////////////////////////
     $CurrentReferences;
     preg_match_all(self::GetLabelsRegex, $wikiPage->getText(), $matches);
     // build it as a "set"
     foreach (array_merge($matches[2], $matches[3]) as $toAdd) {
         if ($toAdd != '') {
             $CurrentReferences[$toAdd] = 1;
         }
     }
     // get the old tags from the database
     /////////////////////////////////////
     $OldReferences;
     if (($rev = $wikiPage->getRevision()) != null && ($prevRev = $rev->getPrevious()) != null) {
         preg_match_all(self::GetLabelsRegex, $prevRev->getText(), $matches);
         // build it as a "set"
         foreach (array_merge($matches[2], $matches[3]) as $toAdd) {
             if ($toAdd != '') {
                 $OldReferences[$toAdd] = 1;
             }
         }
     }
     // Resolve differences
     //////////////////////
     $DB = wfGetDB(DB_MASTER);
     $DB->begin();
     // start a transaction
     // start with the newOnes and make sure that the database is compatable, and remove them
     foreach (array_keys($CurrentReferences) as $RefToMakeSureExists) {
         if (isset($OldReferences[$RefToMakeSureExists])) {
             // if it is already in the array, then we don't have to worry about it; delete it
             unset($OldReferences[$RefToMakeSureExists]);
         } else {
             // if it doesn't exist, we need to add it
             try {
                 $DB->insert(ContentReferencerTableName, array('reference_name' => $RefToMakeSureExists, 'reference_page_name' => (string) $wikiPage->getTitle()));
             } catch (Exception $e) {
                 die($e->getMessage());
             }
         }
     }
     // now, anything left in $OldReferences has been deleted. Let's remove it from the database
     foreach (array_keys($OldReferences) as $RefToDelete) {
         try {
             $DB->delete(ContentReferencerTableName, "reference_name='{$RefToDelete}'");
         } catch (Exception $e) {
             die($e->getMessage());
         }
     }
     $DB->commit();
     // end the transaction
 }
예제 #4
0
	/**
	 * Get text content object
	 * Does *NOT* follow redirects.
	 * TODO: when is this null?
	 *
	 * @note code that wants to retrieve page content from the database should use WikiPage::getContent().
	 *
	 * @return Content|null|boolean false
	 *
	 * @since 1.21
	 */
	protected function fetchContentObject() {
		if ( $this->mContentLoaded ) {
			return $this->mContentObject;
		}

		wfProfileIn( __METHOD__ );

		$this->mContentLoaded = true;
		$this->mContent = null;

		$oldid = $this->getOldID();

		# Pre-fill content with error message so that if something
		# fails we'll have something telling us what we intended.
		//XXX: this isn't page content but a UI message. horrible.
		$this->mContentObject = new MessageContent( 'missing-revision', array( $oldid ), array() );

		if ( $oldid ) {
			# $this->mRevision might already be fetched by getOldIDFromRequest()
			if ( !$this->mRevision ) {
				$this->mRevision = Revision::newFromId( $oldid );
				if ( !$this->mRevision ) {
					wfDebug( __METHOD__ . " failed to retrieve specified revision, id $oldid\n" );
					wfProfileOut( __METHOD__ );
					return false;
				}
			}
		} else {
			if ( !$this->mPage->getLatest() ) {
				wfDebug( __METHOD__ . " failed to find page data for title " . $this->getTitle()->getPrefixedText() . "\n" );
				wfProfileOut( __METHOD__ );
				return false;
			}

			$this->mRevision = $this->mPage->getRevision();

			if ( !$this->mRevision ) {
				wfDebug( __METHOD__ . " failed to retrieve current page, rev_id " . $this->mPage->getLatest() . "\n" );
				wfProfileOut( __METHOD__ );
				return false;
			}
		}

		// @todo FIXME: Horrible, horrible! This content-loading interface just plain sucks.
		// We should instead work with the Revision object when we need it...
		$this->mContentObject = $this->mRevision->getContent( Revision::FOR_THIS_USER, $this->getContext()->getUser() ); // Loads if user is allowed
		$this->mRevIdFetched = $this->mRevision->getId();

		wfRunHooks( 'ArticleAfterFetchContentObject', array( &$this, &$this->mContentObject ) );

		wfProfileOut( __METHOD__ );

		return $this->mContentObject;
	}
예제 #5
0
 /**
  * Get text of an article from database
  * Does *NOT* follow redirects.
  *
  * @return mixed string containing article contents, or false if null
  */
 function fetchContent()
 {
     if ($this->mContentLoaded) {
         return $this->mContent;
     }
     wfProfileIn(__METHOD__);
     $this->mContentLoaded = true;
     $oldid = $this->getOldID();
     # Pre-fill content with error message so that if something
     # fails we'll have something telling us what we intended.
     $t = $this->getTitle()->getPrefixedText();
     $d = $oldid ? wfMsgExt('missingarticle-rev', array('escape'), $oldid) : '';
     $this->mContent = wfMsgNoTrans('missing-article', $t, $d);
     if ($oldid) {
         # $this->mRevision might already be fetched by getOldIDFromRequest()
         if (!$this->mRevision) {
             $this->mRevision = Revision::newFromId($oldid);
             if (!$this->mRevision) {
                 wfDebug(__METHOD__ . " failed to retrieve specified revision, id {$oldid}\n");
                 Wikia::log(__METHOD__, 1, "failed to retrieve specified revision, title '{$t}', id {$oldid}", true);
                 # Wikia change - @author macbre
                 wfProfileOut(__METHOD__);
                 return false;
             }
         }
     } else {
         if (!$this->mPage->getLatest()) {
             wfDebug(__METHOD__ . " failed to find page data for title " . $this->getTitle()->getPrefixedText() . "\n");
             wfProfileOut(__METHOD__);
             return false;
         }
         $this->mRevision = $this->mPage->getRevision();
         if (!$this->mRevision) {
             wfDebug(__METHOD__ . " failed to retrieve current page, rev_id " . $this->mPage->getLatest() . "\n");
             Wikia::log(__METHOD__, 3, "failed to retrieve current page, title '{$t}', rev_id " . $this->mPage->getLatest(), true);
             # Wikia change - @author macbre
             wfProfileOut(__METHOD__);
             return false;
         }
     }
     // @todo FIXME: Horrible, horrible! This content-loading interface just plain sucks.
     // We should instead work with the Revision object when we need it...
     $this->mContent = $this->mRevision->getText(Revision::FOR_THIS_USER);
     // Loads if user is allowed
     $this->mRevIdFetched = $this->mRevision->getId();
     wfRunHooks('ArticleAfterFetchContent', array(&$this, &$this->mContent));
     wfProfileOut(__METHOD__);
     return $this->mContent;
 }
예제 #6
0
 /**
  * Get text of an article from database
  * Does *NOT* follow redirects.
  *
  * @param $oldid Int: 0 for whatever the latest revision is
  * @return mixed string containing article contents, or false if null
  */
 function fetchContent($oldid = 0)
 {
     if ($this->mContentLoaded) {
         return $this->mContent;
     }
     # Pre-fill content with error message so that if something
     # fails we'll have something telling us what we intended.
     $t = $this->getTitle()->getPrefixedText();
     $d = $oldid ? wfMsgExt('missingarticle-rev', array('escape'), $oldid) : '';
     $this->mContent = wfMsgNoTrans('missing-article', $t, $d);
     if ($oldid) {
         $revision = Revision::newFromId($oldid);
         if (!$revision) {
             wfDebug(__METHOD__ . " failed to retrieve specified revision, id {$oldid}\n");
             return false;
         }
         // Revision title doesn't match the page title given?
         if ($this->mPage->getID() != $revision->getPage()) {
             $function = array(get_class($this->mPage), 'newFromID');
             $this->mPage = call_user_func($function, $revision->getPage());
             if (!$this->mPage->getId()) {
                 wfDebug(__METHOD__ . " failed to get page data linked to revision id {$oldid}\n");
                 return false;
             }
         }
     } else {
         if (!$this->mPage->getLatest()) {
             wfDebug(__METHOD__ . " failed to find page data for title " . $this->getTitle()->getPrefixedText() . "\n");
             return false;
         }
         $revision = $this->mPage->getRevision();
         if (!$revision) {
             wfDebug(__METHOD__ . " failed to retrieve current page, rev_id " . $this->mPage->getLatest() . "\n");
             return false;
         }
     }
     // @todo FIXME: Horrible, horrible! This content-loading interface just plain sucks.
     // We should instead work with the Revision object when we need it...
     $this->mContent = $revision->getText(Revision::FOR_THIS_USER);
     // Loads if user is allowed
     $this->mRevIdFetched = $revision->getId();
     $this->mContentLoaded = true;
     $this->mRevision =& $revision;
     wfRunHooks('ArticleAfterFetchContent', array(&$this, &$this->mContent));
     return $this->mContent;
 }
예제 #7
0
 /**
  * @param ParserOutput $parserOutput
  * @param WikiPage $page
  * @param ParserOptions $popts
  * @param string $cacheTime Time when the cache was generated
  * @param int $revId Revision ID that was parsed
  */
 public function save($parserOutput, $page, $popts, $cacheTime = null, $revId = null)
 {
     $expire = $parserOutput->getCacheExpiry();
     if ($expire > 0) {
         $cacheTime = $cacheTime ?: wfTimestampNow();
         if (!$revId) {
             $revision = $page->getRevision();
             $revId = $revision ? $revision->getId() : null;
         }
         $optionsKey = new CacheTime();
         $optionsKey->mUsedOptions = $parserOutput->getUsedOptions();
         $optionsKey->updateCacheExpiry($expire);
         $optionsKey->setCacheTime($cacheTime);
         $parserOutput->setCacheTime($cacheTime);
         $optionsKey->setCacheRevisionId($revId);
         $parserOutput->setCacheRevisionId($revId);
         $parserOutputKey = $this->getParserOutputKey($page, $popts->optionsHash($optionsKey->mUsedOptions, $page->getTitle()));
         // Save the timestamp so that we don't have to load the revision row on view
         $parserOutput->setTimestamp($page->getTimestamp());
         $msg = "Saved in parser cache with key {$parserOutputKey}" . " and timestamp {$cacheTime}" . " and revision id {$revId}" . "\n";
         $parserOutput->mText .= "\n<!-- {$msg} -->\n";
         wfDebug($msg);
         // Save the parser output
         $this->mMemc->set($parserOutputKey, $parserOutput, $expire);
         // ...and its pointer
         $this->mMemc->set($this->getOptionsKey($page), $optionsKey, $expire);
         Hooks::run('ParserCacheSaveComplete', array($this, $parserOutput, $page->getTitle(), $popts, $revId));
     } else {
         wfDebug("Parser output was marked as uncacheable and has not been saved.\n");
     }
 }
 /**
  * @covers WikiPage::doRollback
  */
 public function testDoRollbackFailureSameContent()
 {
     $admin = new User();
     $admin->setName("Admin");
     $admin->addGroup("sysop");
     #XXX: make the test user a sysop...
     $text = "one";
     $page = $this->newPage("WikiPageTest_testDoRollback");
     $page->doEditContent(ContentHandler::makeContent($text, $page->getTitle(), CONTENT_MODEL_WIKITEXT), "section one", EDIT_NEW, false, $admin);
     $rev1 = $page->getRevision();
     $user1 = new User();
     $user1->setName("127.0.1.11");
     $user1->addGroup("sysop");
     #XXX: make the test user a sysop...
     $text .= "\n\ntwo";
     $page = new WikiPage($page->getTitle());
     $page->doEditContent(ContentHandler::makeContent($text, $page->getTitle(), CONTENT_MODEL_WIKITEXT), "adding section two", 0, false, $user1);
     # now, do a the rollback from the same user was doing the edit before
     $resultDetails = array();
     $token = $user1->getEditToken(array($page->getTitle()->getPrefixedText(), $user1->getName()), null);
     $errors = $page->doRollback($user1->getName(), "testing revert same user", $token, false, $resultDetails, $admin);
     $this->assertEquals(array(), $errors, "Rollback failed same user");
     # now, try the rollback
     $resultDetails = array();
     $token = $admin->getEditToken(array($page->getTitle()->getPrefixedText(), $user1->getName()), null);
     $errors = $page->doRollback($user1->getName(), "testing revert", $token, false, $resultDetails, $admin);
     $this->assertEquals(array(array('alreadyrolled', 'WikiPageTest testDoRollback', '127.0.1.11', 'Admin')), $errors, "Rollback not failed");
     $page = new WikiPage($page->getTitle());
     $this->assertEquals($rev1->getSha1(), $page->getRevision()->getSha1(), "rollback did not revert to the correct revision");
     $this->assertEquals("one", $page->getContent()->getNativeData());
 }
예제 #9
0
 /**
  * Get the current content of the page. This is basically similar to
  * WikiPage::getContent( Revision::RAW ) except that when the page doesn't exist an empty
  * content object is returned instead of null.
  *
  * @since 1.21
  * @return Content
  */
 protected function getCurrentContent()
 {
     $rev = $this->page->getRevision();
     $content = $rev ? $rev->getContent(Revision::RAW) : null;
     if ($content === false || $content === null) {
         if (!$this->contentModel) {
             $this->contentModel = $this->getTitle()->getContentModel();
         }
         $handler = ContentHandler::getForModelID($this->contentModel);
         return $handler->makeEmptyContent();
     } else {
         # nasty side-effect, but needed for consistency
         $this->contentModel = $rev->getContentModel();
         $this->contentFormat = $rev->getContentFormat();
         return $content;
     }
 }
예제 #10
0
 /**
  * Get the current content of the page. This is basically similar to
  * WikiPage::getContent( Revision::RAW ) except that when the page doesn't exist an empty
  * content object is returned instead of null.
  *
  * @since 1.21
  * @return Content
  */
 protected function getCurrentContent()
 {
     $rev = $this->page->getRevision();
     $content = $rev ? $rev->getContent(Revision::RAW) : null;
     if ($content === false || $content === null) {
         if (!$this->contentModel) {
             $this->contentModel = $this->getTitle()->getContentModel();
         }
         $handler = ContentHandler::getForModelID($this->contentModel);
         return $handler->makeEmptyContent();
     } elseif (!$this->undidRev) {
         // Content models should always be the same since we error
         // out if they are different before this point (in ->edit()).
         // The exception being, during an undo, the current revision might
         // differ from the prior revision.
         $logger = LoggerFactory::getInstance('editpage');
         if ($this->contentModel !== $rev->getContentModel()) {
             $logger->warning("Overriding content model from current edit {prev} to {new}", ['prev' => $this->contentModel, 'new' => $rev->getContentModel(), 'title' => $this->getTitle()->getPrefixedDBkey(), 'method' => __METHOD__]);
             $this->contentModel = $rev->getContentModel();
         }
         // Given that the content models should match, the current selected
         // format should be supported.
         if (!$content->isSupportedFormat($this->contentFormat)) {
             $logger->warning("Current revision content format unsupported. Overriding {prev} to {new}", ['prev' => $this->contentFormat, 'new' => $rev->getContentFormat(), 'title' => $this->getTitle()->getPrefixedDBkey(), 'method' => __METHOD__]);
             $this->contentFormat = $rev->getContentFormat();
         }
     }
     return $content;
 }
예제 #11
0
 /**
  * Produce page output suitable for indexing.
  *
  * Specific content handlers may override it if they need different content handling.
  *
  * @param WikiPage    $page
  * @param ParserCache $cache
  * @return ParserOutput
  */
 public function getParserOutputForIndexing(WikiPage $page, ParserCache $cache = null)
 {
     $parserOptions = $page->makeParserOptions('canonical');
     $revId = $page->getRevision()->getId();
     if ($cache) {
         $parserOutput = $cache->get($page, $parserOptions);
     }
     if (empty($parserOutput)) {
         $parserOutput = $page->getContent()->getParserOutput($page->getTitle(), $revId, $parserOptions);
         if ($cache) {
             $cache->save($parserOutput, $page, $parserOptions);
         }
     }
     return $parserOutput;
 }
예제 #12
0
 /**
  * @todo FIXME: the above rollback test is better, but it keeps failing in jenkins for some reason.
  */
 public function testDoRollback()
 {
     $admin = new User();
     $admin->setName("Admin");
     $text = "one";
     $page = $this->newPage("WikiPageTest_testDoRollback");
     $page->doEditContent(ContentHandler::makeContent($text, $page->getTitle(), CONTENT_MODEL_WIKITEXT), "section one", EDIT_NEW, false, $admin);
     $rev1 = $page->getRevision();
     $user1 = new User();
     $user1->setName("127.0.1.11");
     $text .= "\n\ntwo";
     $page = new WikiPage($page->getTitle());
     $page->doEditContent(ContentHandler::makeContent($text, $page->getTitle(), CONTENT_MODEL_WIKITEXT), "adding section two", 0, false, $user1);
     # now, try the rollback
     $admin->addGroup("sysop");
     #XXX: make the test user a sysop...
     $token = $admin->getEditToken(array($page->getTitle()->getPrefixedText(), $user1->getName()), null);
     $errors = $page->doRollback($user1->getName(), "testing revert", $token, false, $details, $admin);
     if ($errors) {
         $this->fail("Rollback failed:\n" . print_r($errors, true) . ";\n" . print_r($details, true));
     }
     $page = new WikiPage($page->getTitle());
     $this->assertEquals($rev1->getSha1(), $page->getRevision()->getSha1(), "rollback did not revert to the correct revision");
     $this->assertEquals("one", $page->getContent()->getNativeData());
 }