Merge branch 'InternalParseBeforeLinks-hook'

Conflicts:
	LinkTitles.body.php
	SpecialLinkTitles.php
This commit is contained in:
Daniel Kraus
2014-06-11 16:57:18 +02:00
2 changed files with 45 additions and 49 deletions

View File

@ -53,46 +53,42 @@
$wgHooks['PageContentSave'][] = 'LinkTitles::onPageContentSave'; $wgHooks['PageContentSave'][] = 'LinkTitles::onPageContentSave';
}; };
if ( $wgLinkTitlesParseOnRender ) { if ( $wgLinkTitlesParseOnRender ) {
$wgHooks['ArticleAfterFetchContentObject'][] = $wgHooks['InternalParseBeforeLinks'][] = 'LinkTitles::onInternalParseBeforeLinks';
'LinkTitles::onArticleAfterFetchContentObject';
}; };
$wgHooks['GetDoubleUnderscoreIDs'][] = 'LinkTitles::onGetDoubleUnderscoreIDs'; $wgHooks['GetDoubleUnderscoreIDs'][] = 'LinkTitles::onGetDoubleUnderscoreIDs';
} }
/// Event handler that is hooked to the ArticleSave event. /// Event handler that is hooked to the PageContentSave event.
public static function onPageContentSave( &$wikiPage, &$user, &$content, &$summary, public static function onPageContentSave( &$wikiPage, &$user, &$content, &$summary,
$isMinor, $isWatch, $section, &$flags, &$status ) { $isMinor, $isWatch, $section, &$flags, &$status ) {
// To prevent time-consuming parsing of the page whenever if ( ! $isMinor ) {
// it is edited and saved, we only parse it if the flag $title = $wikiPage->getTitle();
// 'minor edits' is not set. $text = $content->getContentHandler()->serializeContent($content);
return $isMinor or self::parseContent( $wikiPage, $content ); $newText = self::parseContent( $title, $text );
if ( $newText != $text ) {
$content = $content->getContentHandler()->unserializeContent( $newText );
} }
/// Event handler that is hooked to the ArticleAfterFetchContent event.
/// @param $article Article object
/// @param $content Content object that holds the article content
public static function onArticleAfterFetchContentObject( &$article, &$content ) {
// The ArticleAfterFetchContentObject event is triggered whenever page
// content is retrieved from the database, i.e. also for editing etc.
// Therefore we access the global $action variabl to only parse the
// content when the page is viewed.
global $action;
if ( in_array( $action, array('view', 'render', 'purge') ) ) {
self::parseContent( $article, $content );
}; };
return true; return true;
} }
/// Event handler that is hooked to the InternalParseBeforeLinks event.
/// @param Parser $parser Parser that raised the event.
/// @param $text Preprocessed text of the page.
public static function onInternalParseBeforeLinks( Parser &$parser, &$text ) {
$title = $parser->getTitle();
$text = self::parseContent( $title, $text );
return true;
}
/// Core function of the extension, performs the actual parsing of the content. /// Core function of the extension, performs the actual parsing of the content.
/// @param $article Article object /// @param Title $title Title of the page being parsed
/// @param $content Content object that holds the article content /// @param $text String that holds the article content
/// @returns true /// @returns string: parsed text with links added if needed
static function parseContent( WikiPage &$wikiPage, Content &$content ) { private static function parseContent( Title &$title, &$text ) {
// If the page contains the magic word '__NOAUTOLINKS__', do not parse // If the page contains the magic word '__NOAUTOLINKS__', do not parse it.
// the content. if ( MagicWord::get('MAG_LINKTITLES_NOAUTOLINKS')->match( $text ) ) {
if ( $content->matchMagicWord(
MagicWord::get('MAG_LINKTITLES_NOAUTOLINKS') ) ) {
return true; return true;
} }
@ -121,8 +117,7 @@
$templatesDelimiter = '{{[^|]+?}}|{{.+\||'; $templatesDelimiter = '{{[^|]+?}}|{{.+\||';
}; };
LinkTitles::$currentTitle = $wikiPage->getTitle(); LinkTitles::$currentTitle = $title;
$text = $content->getContentHandler()->serializeContent($content);
$newText = $text; $newText = $text;
// Build a regular expression that will capture existing wiki links ("[[...]]"), // Build a regular expression that will capture existing wiki links ("[[...]]"),
@ -151,8 +146,8 @@
// Build a blacklist of pages that are not supposed to be link // Build a blacklist of pages that are not supposed to be link
// targets. This includes the current page. // targets. This includes the current page.
$black_list = str_replace( '_', ' ', $blackList = str_replace( '_', ' ',
'("' . implode( '", "',$wgLinkTitlesBlackList ) . '("' . implode( '", "',$wgLinkTitlesBlackList ) . '", "' .
LinkTitles::$currentTitle->getDbKey() . '")' ); LinkTitles::$currentTitle->getDbKey() . '")' );
// Build an SQL query and fetch all page titles ordered by length from // Build an SQL query and fetch all page titles ordered by length from
@ -167,7 +162,7 @@
array( array(
'page_namespace = 0', 'page_namespace = 0',
'CHAR_LENGTH(page_title) >= ' . $wgLinkTitlesMinimumTitleLength, 'CHAR_LENGTH(page_title) >= ' . $wgLinkTitlesMinimumTitleLength,
'page_title NOT IN ' . $black_list, 'page_title NOT IN ' . $blackList,
), ),
__METHOD__, __METHOD__,
array( 'ORDER BY' => 'CHAR_LENGTH(page_title) ' . $sort_order ) array( 'ORDER BY' => 'CHAR_LENGTH(page_title) ' . $sort_order )
@ -179,7 +174,7 @@
array( array(
'page_namespace = 0', 'page_namespace = 0',
'LENGTH(page_title) >= ' . $wgLinkTitlesMinimumTitleLength, 'LENGTH(page_title) >= ' . $wgLinkTitlesMinimumTitleLength,
'page_title NOT IN ' . $black_list, 'page_title NOT IN ' . $blackList,
), ),
__METHOD__, __METHOD__,
array( 'ORDER BY' => 'LENGTH(page_title) ' . $sort_order ) array( 'ORDER BY' => 'LENGTH(page_title) ' . $sort_order )
@ -241,31 +236,32 @@
$newText = implode( '', $arr ); $newText = implode( '', $arr );
} // $wgLinkTitlesSmartMode } // $wgLinkTitlesSmartMode
}; // foreach $res as $row }; // foreach $res as $row
if ( $newText != $text ) { return $newText;
$content = $content->getContentHandler()->unserializeContent( $newText );
}
return true;
} }
/// Automatically processes a single page, given a $title Title object. /// Automatically processes a single page, given a $title Title object.
/// This function is called by the SpecialLinkTitles class and the /// This function is called by the SpecialLinkTitles class and the
/// LinkTitlesJob class. /// LinkTitlesJob class.
/// @param string $title Page title. /// @param string $title Page title.
/// @param IContextProvider $context Object that implements IContextProvider. /// @param RequestContext $context Current context.
/// If in doubt, call MediaWiki's `RequestContext::getMain()` /// If in doubt, call MediaWiki's `RequestContext::getMain()`
/// to obtain such an object. /// to obtain such an object.
/// @returns undefined /// @returns undefined
public static function processPage($title, IContextProvider $context) { public static function processPage($title, RequestContext $context) {
// TODO: make this namespace-aware // TODO: make this namespace-aware
$titleObj = Title::makeTitle(0, $title); $titleObj = Title::makeTitle(0, $title);
$page = WikiPage::factory($titleObj); $page = WikiPage::factory($titleObj);
$content = $page->getContent(); $content = $page->getContent();
LinkTitles::parseContent($page, $content); $text = $content->getContentHandler()->serializeContent($content);
$newText = LinkTitles::parseContent($titleObj, $text);
if ( $text != $newText ) {
$content = $content->getContentHandler()->unserializeContent( $newText );
$page->doQuickEditContent($content, $page->doQuickEditContent($content,
$context->getUser(), $context->getUser(),
"Links to existing pages added by LinkTitles bot.", "Links to existing pages added by LinkTitles bot.",
true // minor modification true // minor modification
); );
};
} }
/// Adds the two magic words defined by this extension to the list of /// Adds the two magic words defined by this extension to the list of

View File

@ -76,8 +76,8 @@ class SpecialLinkTitles extends SpecialPage {
/// processed, returns the title of the next page that needs processing. /// processed, returns the title of the next page that needs processing.
/// @param WebRequest $request WebRequest object that is associated with the special /// @param WebRequest $request WebRequest object that is associated with the special
/// page. /// page.
/// @param Output $output Output object that the special page is equipped with. /// @param OutputPage $output Output page for the special page.
private function process( WebRequest &$request, Output &$output) { private function process( WebRequest &$request, OutputPage &$output) {
global $wgLinkTitlesTimeLimit; global $wgLinkTitlesTimeLimit;
// Start the stopwatch // Start the stopwatch