26 error_log(print_r($var, TRUE) .
"\n", 3,
'php://stderr');
33 private static $currentTitle;
36 private static $targetTitle;
41 private static $targetContent;
45 private static $targetTitleText;
48 public static function setup() {
52 if ( $wgLinkTitlesParseOnEdit ) {
53 $wgHooks[
'PageContentSave'][] =
'LinkTitles::onPageContentSave';
55 if ( $wgLinkTitlesParseOnRender ) {
56 $wgHooks[
'InternalParseBeforeLinks'][] =
'LinkTitles::onInternalParseBeforeLinks';
58 $wgHooks[
'GetDoubleUnderscoreIDs'][] =
'LinkTitles::onGetDoubleUnderscoreIDs';
63 $isMinor, $isWatch, $section, &$flags, &$status ) {
66 $title = $wikiPage->getTitle();
67 $text = $content->getContentHandler()->serializeContent($content);
68 $newText = self::parseContent( $title, $text );
69 if ( $newText != $text ) {
70 $content = $content->getContentHandler()->unserializeContent( $newText );
80 $title = $parser->getTitle();
81 $text = self::parseContent( $title, $text );
89 private static function parseContent( Title &$title, &$text ) {
91 if ( MagicWord::get(
'MAG_LINKTITLES_NOAUTOLINKS')->match( $text ) ) {
105 global $wgCapitalLinks;
118 if ( $wgLinkTitlesSkipTemplates )
120 $templatesDelimiter =
'{{[^}]+}}|';
130 $templatesDelimiter =
'{{[^|]*?(?:(?:\[\[[^]]+]])?)[^|]*?(?:\|(?:\w+=)?|(?:}}))|\|\w+=|';
133 LinkTitles::$currentTitle = $title;
144 $urlPattern =
'[a-z]+?\:\/\/(?:\S+\.)+\S+(?:\/.*)?';
148 $templatesDelimiter .
149 '^ .+?\n|\n .+?\n|\n .+?$|^ .+?$|' .
150 '<nowiki>.*?<.nowiki>|<code>.*?<\/code>|' .
151 '<pre>.*?<\/pre>|<html>.*?<\/html>|' .
152 '<script>.*?<\/script>|' .
153 '<div.+?>|<\/div>|' .
154 '<span.+?>|<\/span>|' .
155 '<file>[^<]*<\/file>|' .
156 'style=".+?"|class=".+?"|' .
157 '\[' . $urlPattern .
'\s.+?\]|'. $urlPattern .
'(?=\s|$)|' .
158 '(?<=\b)\S+\@(?:\S+\.)+\S+(?=\b)' .
163 $blackList = str_replace(
'_',
' ',
164 '("' . implode(
'", "',$wgLinkTitlesBlackList ) .
'", "' .
165 LinkTitles::$currentTitle->getDbKey() .
'")' );
171 $dbr = wfGetDB( DB_SLAVE );
177 'page_namespace = 0',
178 'CHAR_LENGTH(page_title) >= ' . $wgLinkTitlesMinimumTitleLength,
179 'page_title NOT IN ' . $blackList,
182 array(
'ORDER BY' =>
'CHAR_LENGTH(page_title) ' . $sort_order )
184 }
catch (Exception $e) {
189 'page_namespace = 0',
190 'LENGTH(page_title) >= ' . $wgLinkTitlesMinimumTitleLength,
191 'page_title NOT IN ' . $blackList,
194 array(
'ORDER BY' =>
'LENGTH(page_title) ' . $sort_order )
199 foreach( $res as $row ) {
200 LinkTitles::newTarget( $row->page_title );
205 $arr = preg_split( $delimiter, $newText, -1, PREG_SPLIT_DELIM_CAPTURE );
209 LinkTitles::$targetTitleText = LinkTitles::$targetTitle->getText();
210 $quotedTitle = preg_quote(LinkTitles::$targetTitleText,
'/');
216 if ( $wgCapitalLinks && ( $quotedTitle[0] !=
'\\' )) {
217 $searchTerm =
'((?i)' . $quotedTitle[0] .
'(?-i)' .
218 substr($quotedTitle, 1) .
')';
220 $searchTerm =
'(' . $quotedTitle .
')';
223 for ( $i = 0; $i < count( $arr ); $i+=2 ) {
225 $arr[$i] = preg_replace_callback(
'/(?<![\:\.\@\/\?\&])' .
226 $wordStartDelim . $searchTerm . $wordEndDelim .
'/u',
227 array(
'LinkTitles',
'simpleModeCallback'), $arr[$i], $limit, $count );
228 if (( $limit >= 0 ) && ( $count > 0 )) {
232 $newText = implode(
'', $arr );
237 if ($wgLinkTitlesSmartMode) {
238 $arr = preg_split( $delimiter, $newText, -1, PREG_SPLIT_DELIM_CAPTURE );
240 for ( $i = 0; $i < count( $arr ); $i+=2 ) {
242 $arr[$i] = preg_replace_callback(
'/(?<![\:\.\@\/\?\&])' .
243 $wordStartDelim .
'(' . $quotedTitle .
')' .
244 $wordEndDelim .
'/iu', array(
'LinkTitles',
'smartModeCallback'),
245 $arr[$i], $limit, $count );
246 if (( $limit >= 0 ) && ( $count > 0 )) {
250 $newText = implode(
'', $arr );
264 public static function processPage($title, RequestContext $context) {
266 $titleObj = Title::makeTitle(0, $title);
267 $page = WikiPage::factory($titleObj);
268 $content = $page->getContent();
269 $text = $content->getContentHandler()->serializeContent($content);
270 $newText = LinkTitles::parseContent($titleObj, $text);
271 if ( $text != $newText ) {
272 $content = $content->getContentHandler()->unserializeContent( $newText );
273 $page->doQuickEditContent($content,
275 "Links to existing pages added by LinkTitles bot.",
287 $doubleUnderscoreIDs[] =
'MAG_LINKTITLES_NOTARGET';
288 $doubleUnderscoreIDs[] =
'MAG_LINKTITLES_NOAUTOLINKS';
293 private static function simpleModeCallback( array $matches ) {
294 if ( LinkTitles::checkTargetPage() ) {
295 return '[[' . $matches[0] .
']]';
310 private static function smartModeCallback( array $matches ) {
311 global $wgCapitalLinks;
313 if ( $wgCapitalLinks ) {
318 if ( LinkTitles::checkTargetPage() ) {
319 if ( strcmp(substr(LinkTitles::$targetTitleText, 1), substr($matches[0], 1)) == 0 ) {
321 return '[[' . $matches[0] .
']]';
324 return '[[' . LinkTitles::$targetTitleText .
'|' . $matches[0] .
']]';
334 if ( LinkTitles::checkTargetPage() ) {
335 if ( strcmp(LinkTitles::$targetTitleText, $matches[0]) == 0 ) {
337 return '[[' . $matches[0] .
']]';
340 return '[[' . LinkTitles::$targetTitleText .
'|' . $matches[0] .
']]';
351 private static function newTarget( $title ) {
353 LinkTitles::$targetTitle = Title::makeTitle( NS_MAIN, $title);
354 LinkTitles::$targetContent = null;
363 private static function getTargetContent() {
364 if ( ! isset( $targetContent ) ) {
365 LinkTitles::$targetContent = WikiPage::factory(
366 LinkTitles::$targetTitle)->getContent();
368 return LinkTitles::$targetContent;
377 private static function checkTargetPage() {
384 if ( $wgLinkTitlesCheckRedirect ) {
385 $redirectTitle = LinkTitles::getTargetContent()->getUltimateRedirectTarget();
386 if ( $redirectTitle && $redirectTitle->equals(LinkTitles::$currentTitle) ) {
394 if ( $wgLinkTitlesEnableNoTargetMagicWord ) {
395 if ( LinkTitles::getTargetContent()->matchMagicWord(
396 MagicWord::get(
'MAG_LINKTITLES_NOTARGET') ) ) {
Central class of the extension.
dump($var)
Helper function for development and debugging.
$wgLinkTitlesBlackList
Blacklist of page titles that should never be linked.
$wgLinkTitlesWordEndOnly
Determines whether a page title must end with the end of a word in order for it to be linked...
$wgLinkTitlesFirstOnly
Determines whether to link only the first occurrence of a page title on a page or all occurrences...
$wgLinkTitlesEnableNoTargetMagicWord
Determines whether or not the magic word NOAUTOLINKTARGET is enabled or not.
$wgLinkTitlesSkipTemplates
Determines whether to parse text inside templates.
$wgLinkTitlesParseHeadings
Determines whether or not to insert links into headings.
$wgLinkTitlesPreferShortTitles
Controls precedence of page titles.
static onPageContentSave(&$wikiPage, &$user, &$content, &$summary, $isMinor, $isWatch, $section, &$flags, &$status)
Event handler that is hooked to the PageContentSave event.
$wgLinkTitlesWordStartOnly
Determines whether a page title must occur at the start of a word in order for it to be linked...
$wgLinkTitlesMinimumTitleLength
The minimum number of characters in a title that is required for it to be automatically linked to...
static onGetDoubleUnderscoreIDs(array &$doubleUnderscoreIDs)
Adds the two magic words defined by this extension to the list of 'double-underscore' terms that are ...
$wgLinkTitlesParseOnRender
Important configuration variable that determines when the extension will process a page...
$wgLinkTitlesSmartMode
Important setting that controls the extension's smart mode of operation.
static onInternalParseBeforeLinks(Parser &$parser, &$text)
Event handler that is hooked to the InternalParseBeforeLinks event.
$wgLinkTitlesParseOnEdit
Important configuration variable that determines when the extension will process a page...
static setup()
Setup function, hooks the extension's functions to MediaWiki events.
static processPage($title, RequestContext $context)
Automatically processes a single page, given a $title Title object.
$wgLinkTitlesCheckRedirect
Determines whether or not to check if a page redirects to the current page.