Created
March 31, 2015 03:40
-
-
Save songmw90/05c63e5d18a896eff881 to your computer and use it in GitHub Desktop.
AutoLink_for_Mediawiki_1.2_higher
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * AutoLink extension | |
| * Turn ordinary words into page links, if the name matches. to match plurals and variations, | |
| * write lots and lots of redirection pages. | |
| * The original version, by [http://www.mediawiki.org/wiki/User:Sanjualone Sanjeev], required | |
| * users to manually enter all the page names they wanted to match. | |
| * [http://www.mediawiki.org/wiki/User:Gelisam] completely rewrote the script (minus the | |
| * boilerplate) to match any page. | |
| * | |
| * On 08/24/2007, a new version was created by [http://www.mediawiki.org/wiki/User:Vjg] which | |
| * gives preference to longer page names. It switches the order of processing, handling the | |
| * article for each page, but only building the page array once. The previous version handled | |
| * the article once, but built the page array on each pass. I haven't fully explored all the | |
| * performance implications. This was for use on a relatively small site. | |
| * | |
| * on 09/10/2008, a new version was created by Krishna Maheshwari | |
| * which doesn't add a pipe & link if the page name matches the text (longest matches first). It also strips all links | |
| * prior to regenerating them, ensuring if changes or other articles are created with longer names | |
| * that match, than they are used. Ie: This Text could be transformed to This [[Text]] than on a | |
| * subsequent edit become [[This Text]]. In addition, it only allows the first occurance of a page | |
| * to be linked instead of each occurance. This extension is used on Hindupedia (www.hindupedia.com) | |
| * New Tags: __NOAUTOLINK__ => this extension doesn't try to generate any links for page | |
| * __NOREGENERATELINKS__ => don't try to regenerate links | |
| * <noautolink> ... </noautolink> => don't generate links on content inside these tags | |
| * | |
| * On 12/25/2008, a new version was created by Hyunsik Kim | |
| * completly rewritten version. Main function refer to the version 2.4 | |
| * magic word function has been removed because I don't know what it is. | |
| * reduce regex functions and replace faster one, improve getting title function. | |
| * consider nested tag structure. | |
| * longest match uses first. | |
| * -- v3.2 : Bug fix - MakeRegion | |
| * -- v3.3 : Improve Regioning function - Increase speed. | |
| * -- v3.5 : Feature added Autolink execute when view page. | |
| * -- 12/26/2008, v3.6 : Increse Parse speed. | |
| * -- 12/27/2008, v3.7 : Bug fix - Prevent link strip at protected block. | |
| * | |
| * @author Hyunsik Kim (E-mail:[email protected]) | |
| * @version 3.7 | |
| * @url http://www.mediawiki.org/wiki/Extension:AutoLink | |
| */ | |
| if (!defined('MEDIAWIKI')) die(); | |
| $wgExtensionCredits['other'][] = array( | |
| 'name' => 'AutoLink', | |
| 'version' => '3.7', | |
| 'author' => 'Hyunsik Kim', | |
| 'url' => 'http://www.mediawiki.org/wiki/Extension:AutoLink', | |
| ); | |
| ########################## Enable Autolink ########################### | |
| # We don't recommend both options has been enabled at the same time. # | |
| # To activate Autolink after edit page, uncomment this: | |
| #$wgHooks['ArticleSave'][] = 'wfAutoLink_ArticleSave'; | |
| # To activate Autolink during page view, uncomment this: | |
| $wgHooks['ArticleAfterFetchContentObject'][] = 'wfAutoLink_ArticleAfterFetchContent'; | |
| # Event Handler for ArticleAfterFetchContent Event. | |
| function wfAutoLink_ArticleAfterFetchContent($article, Content $content ) | |
| { | |
| global $action; | |
| $currentPage = $article->mTitle->mTextform; | |
| # Actions : view, watch, unwatch, delete, revert, rollback, protect, unprotect, | |
| # info, markpatrolled, render, deletetrackback, purge, print, dublincore, | |
| # creativecommons, credits, submit, edit, editredlink, history, raw, ajax | |
| # Refer to [http://www.mediawiki.org/wiki/Manual:Page_action#Actions] | |
| switch( $action ) | |
| { | |
| case '': | |
| case 'view': | |
| case 'render': | |
| case 'purge': | |
| case 'print': | |
| $content->mText = AutoLink_Parse($currentPage, $content->mText ); | |
| break; | |
| case 'edit': | |
| case 'editredlink': | |
| break; | |
| default: | |
| break; | |
| } | |
| return true; | |
| } | |
| # Event Handler for ArticleSave Event. | |
| function wfAutoLink_ArticleSave($article, $user, $text) | |
| { | |
| return AutoLink_Parse($article->mTitle->mTextform, $text); | |
| } | |
| function AutoLink_Parse($title, $text) | |
| { | |
| # Set ignoring blocks. It must include "[[" and "]]" | |
| # Otherwise, It may cause endless recursion. | |
| $ignoreBlocks = array( | |
| array("[[", "]]"), | |
| array("[", "]"), | |
| array("{{", "}}"), | |
| array("<pre", "</pre>"), | |
| array("<nowiki>", "</nowiki>"), | |
| array("<noautolink>","</noautolink>"), | |
| array("<createbox>", "</createbox>"), | |
| array("<categorytree>", "</categorytree>"), | |
| array("<DPL>", "</DPL>"), | |
| array("#REDIRECT", "]]"), | |
| ); | |
| $currentPage = str_replace(" ", "_", $title); | |
| # If we specificy no autolink, than don't autolink | |
| if (stripos($text, '__NOAUTOLINK__') !== false) { return true; } | |
| # As long as we are allowed to regenerate links... | |
| if (stripos($text, '__NOREGENERATELINKS__') === false) | |
| { | |
| # Strip links so that all links are regenerated except those that are custom links | |
| # ie have a '|' or ')' or '(' in them | |
| # It only work for odd number region(Protected area). | |
| $region = AutoLink_MakeRegion($text, $ignoreBlocks); | |
| for ( $i = 1; $i < count($region); $i += 2) | |
| { | |
| $region[$i] = preg_replace('/^\[\[([^|:\(\)\]]*)\]\]$/','\1',$region[$i]); | |
| } | |
| # Merge regions so that all stripped links are unprotected. | |
| $text = implode($region); | |
| } | |
| $titles = AutoLink_GetTitleList($currentPage); | |
| return AutoLink_MakeLink($titles, $text, $ignoreBlocks); | |
| } | |
| function AutoLink_GetTitleList($currentPage) | |
| { | |
| $dbr = &wfGetDB(DB_SLAVE); | |
| $result = $dbr->select('page', array('page_title'), 'page_namespace=0 AND page_title <> "'.$currentPage.'"', __METHOD__, array('ORDER BY' =>'CHAR_LENGTH(page_title) DESC')); | |
| $titles = array(); | |
| while (($row = $dbr->fetchObject($result))) | |
| { | |
| $titles[] = $row->page_title; | |
| } | |
| $dbr->freeResult($result); | |
| return $titles; | |
| } | |
| function AutoLink_FindFirstSkipBlock($ignoreBlocks, $text) | |
| { | |
| $startTag = ""; | |
| $endTag = ""; | |
| $firstTag_start = strlen($text) + 1; # sentinel value | |
| foreach($ignoreBlocks as $tagPair) | |
| { | |
| $curTag_start = stripos($text, $tagPair[0]); | |
| if ( $curTag_start !== false && $firstTag_start > $curTag_start ) | |
| { | |
| $startTag = $tagPair[0]; | |
| $endTag = $tagPair[1]; | |
| $firstTag_start = $curTag_start; | |
| } | |
| } | |
| if ( $firstTag_start > strlen($text) ) return false; | |
| $startTagLength = strlen($startTag); | |
| $endTagLength = strlen($endTag); | |
| $firstTag_end = stripos($text, $endTag, $firstTag_start + $startTagLength); | |
| $nextPosition = $firstTag_start + $startTagLength; | |
| $tagDepth = 0; | |
| while ( true ) | |
| { | |
| $findPosition = stripos($text, $startTag, $nextPosition); | |
| if ( $findPosition === false || $findPosition > $firstTag_end ) | |
| { | |
| break; | |
| } | |
| $nextPosition = $findPosition + $startTagLength; | |
| ++$tagDepth; | |
| } | |
| $nextPosition = $firstTag_end + $endTagLength; | |
| while ( $tagDepth > 0 ) | |
| { | |
| $findPosition = stripos($text, $endTag, $nextPosition); | |
| # If orpant tag has been detected, whole block is selected. | |
| if ( $findPosition === false ) | |
| { | |
| $nextPosition = strlen($text); | |
| break; | |
| } | |
| $nextPosition = $findPosition + $endTagLength; | |
| --$tagDepth; | |
| } | |
| $firstTag_end = $nextPosition; | |
| return array($firstTag_start, $firstTag_end); | |
| } | |
| function AutoLink_MakeRegion($text, $ignoreBlocks) | |
| { | |
| $textLength = strlen($text); | |
| # Region :: Even : Normal text area, Odd : Protected area(skip autolink) | |
| $region = array(); | |
| $skipBlock = AutoLink_FindFirstSkipBlock($ignoreBlocks, $text); | |
| # Recursion Terminate condition | |
| if ( $skipBlock === false ) | |
| { | |
| return array($text); | |
| } | |
| $splitBegin = $skipBlock[0]; | |
| $splitEnd = $skipBlock[1]; | |
| $region = array_merge( | |
| array(substr($text, 0, $splitBegin), | |
| substr($text, $splitBegin, $splitEnd - $splitBegin)), | |
| AutoLink_MakeRegion(substr($text, $splitEnd , $textLength - $splitEnd), $ignoreBlocks) | |
| ); | |
| return $region; | |
| } | |
| function AutoLink_MakeLink($titles, $text, $ignoreBlocks) | |
| { | |
| $autoLinkTag = array(array("[[","]]")); | |
| $region = AutoLink_MakeRegion($text, $ignoreBlocks); | |
| foreach($titles as $page) | |
| { | |
| $pattern = str_replace('_','[_ ]', preg_quote($page, '/')); | |
| $patternLength = strlen($page); | |
| $replace = '[['.str_replace('_', ' ', $page).']]'; | |
| # Make links. It only work for even number region. | |
| # Odd number region is ignoring block(include already linked text) | |
| for ( $i = 0; $i < count($region); ) | |
| { | |
| if ( strlen($region[$i]) < $patternLength ) | |
| { | |
| $i += 2; | |
| continue; | |
| } | |
| $region[$i] = preg_replace('/'.$pattern.'/i', $replace, $region[$i]); | |
| $newRegion = AutoLink_MakeRegion($region[$i], $autoLinkTag); | |
| array_splice($region, $i, 1, $newRegion); | |
| $i += count($newRegion) + 1; | |
| } | |
| } | |
| $text = implode($region); | |
| return $text; | |
| } | |
| ?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment