예제 #1
0
	/**
	 * Retrieves an article parsed output either from parser cache or by
	 * parsing it again. If parsing again, stores it back into parser cache.
	 *
	 * @param $title Article title object.
	 * @param $feed Whether the result should be part of a feed.
	 * @return Two-element array containing the article and its parser output.
	 *
	 * @note Mw1.16+ provides Article::getParserOptions() and
	 *   Article::getParserOutput(), that could be used here in the future.
	 *   The problem is that getParserOutput() uses ParserCache exclusively,
	 *   which means that only ParserOptions control the key used to store
	 *   the output in the cache and there is no hook yet in
	 *   ParserCache::getKey() to set these extra bits (and the
	 *   'PageRenderingCache' hook is not useful here, it is in the wrong
	 *   place without access to the parser options). This is certainly
	 *   something that should be fixed in the future.  FIXME
	 *
	 * @note This function makes a clone of the parser if
	 *   $wgWikilogCloneParser is set, but cloning the parser is not
	 *   officially supported. The problem here is that we need a different
	 *   parser that we could mess up without interfering with normal page
	 *   rendering, and we can't create a new instance because of too many
	 *   broken extensions around. Check self::parserSanityCheck().
	 */
	public static function parsedArticle( Title $title, $feed = false ) {
		global $wgWikilogCloneParser;
		global $wgUser, $wgEnableParserCache;
		global $wgParser, $wgParserConf;

		static $parser = null;

		$article = new Article( $title );

		# First try the parser cache.
		$useParserCache = $wgEnableParserCache &&
			intval( $wgUser->getOption( 'stubthreshold' ) ) == 0 &&
			$article->exists();
		$parserCache = ParserCache::singleton();

		# Parser options.
		$parserOpt = ParserOptions::newFromUser( $wgUser );
		$parserOpt->setTidy( true );
		if ( $feed ) {
			$parserOpt->setEditSection( false );

			$parserOpt->addExtraKey( "WikilogFeed" );
		} else {
			$parserOpt->enableLimitReport();
		}

		if ( $useParserCache ) {
			# Look for the parsed article output in the parser cache.
			$parserOutput = $parserCache->get( $article, $parserOpt );

			# On success, return the object retrieved from the cache.
			if ( $parserOutput ) {
				return array( $article, $parserOutput );
			}
		}

		# Enable some feed-specific behavior.
		if ( $feed ) {
			$saveFeedParse = WikilogParser::enableFeedParsing();
			$saveExpUrls = WikilogParser::expandLocalUrls();
		}

		# Get a parser instance, if not already cached.
		if ( is_null( $parser ) ) {
			if ( !StubObject::isRealObject( $wgParser ) ) {
				$wgParser->_unstub();
			}
			if ( $wgWikilogCloneParser ) {
				$parser = clone $wgParser;
			} else {
				$class = $wgParserConf['class'];
				$parser = new $class( $wgParserConf );
			}
		}
		$parser->startExternalParse( $title, $parserOpt, Parser::OT_HTML );

		# Parse article.
		$arttext = $article->fetchContent();
		$parserOutput = $parser->parse( $arttext, $title, $parserOpt );

		# Save in parser cache.
		if ( $useParserCache && $parserOutput->getCacheTime() != -1 ) {
			$parserCache->save( $parserOutput, $article, $parserOpt );
		}

		# Restore default behavior.
		if ( $feed ) {
			WikilogParser::enableFeedParsing( $saveFeedParse );
			WikilogParser::expandLocalUrls( $saveExpUrls );
		}

		return array( $article, $parserOutput );
	}