Extension:LandingPage/LandingPage.php

From MediaWiki.org
Jump to navigation Jump to search
<?php
//
// LandingPage MediaWiki extension.
// Follows redirections to landing page.
// 
// Copyright (C) 2009 - John Erling Blad.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

# Not a valid entry point, skip unless MEDIAWIKI is defined
if( !defined( 'MEDIAWIKI' ) ) {
	echo "LandingPage: This is an extension to the MediaWiki package and cannot be run standalone.\n";
	die( -1 );
}
 
#----------------------------------------------------------------------------
#    Extension initialization
#----------------------------------------------------------------------------
 
$wgLandingPage = array();
$LandingPageVersion = '0.5';
$wgExtensionCredits['parserhook'][] = array(
	'name'=>'LandingPage',
	'version'=>$LandingPageVersion,
	'author'=>'John Erling Blad',
	'url'=>'http://www.mediawiki.org/wiki/Extension:LandingPage',
	'description' => 'Follows redirections to landing page'
    );
 
$dir = dirname(__FILE__) . '/';
$wgExtensionFunctions[] = 'wfLandingPageSetup';
$wgHooks['LanguageGetMagic'][] = 'wfLandingPageMagic';
$wgExtensionMessagesFiles['LandingPage'] = $dir . 'LandingPage.i18n.php';

#$wgLandingPageAlias['en'] = 'LANDINGPAGE';

function wfLandingPageSetup() {
	global $wgParser;
	wfLoadExtensionMessages('LandingPage');
	$wgParser->setFunctionHook( 'LANDINGPAGE', 'wfRenderLandingPage_LANDINGPAGE', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGPAGELINK', 'wfRenderLandingPage_LANDINGPAGELINK', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGSUBPAGE', 'wfRenderLandingPage_LANDINGSUBPAGE', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGSUBPAGELINK', 'wfRenderLandingPage_LANDINGSUBPAGELINK', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGPREFIXED', 'wfRenderLandingPage_LANDINGPREFIXED', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGPREFIXEDLINK', 'wfRenderLandingPage_LANDINGPREFIXEDLINK', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGUSER', 'wfRenderLandingPage_LANDINGUSER', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGUSERLINK', 'wfRenderLandingPage_LANDINGUSERLINK', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGREALUSER', 'wfRenderLandingPage_LANDINGREALUSER', SFH_NO_HASH );
	$wgParser->setFunctionHook( 'LANDINGREALUSERLINK', 'wfRenderLandingPage_LANDINGREALUSERLINK', SFH_NO_HASH );
}
 
function wfLandingPageMagic( &$magicWords, $langCode ) {

	#choose the text to id mapping based on language
	switch ( $langCode ) {
	
	# Norwegian (bokmål) and default mapping
	case 'no':
		$magicWords['LANDINGPAGE'] = array( 1, 'MÅLSIDE', 'LANDINGPAGE' );
		$magicWords['LANDINGPAGELINK'] = array( 1, 'MÅLSIDELENKE', 'LANDINGPAGELINK' );
		$magicWords['LANDINGSUBPAGE'] = array( 1, 'MÅLUNDERSIDE', 'LANDINGSUBPAGE' );
		$magicWords['LANDINGSUBPAGELINK'] = array( 1, 'MÅLUNDERSIDELENKE', 'LANDINGSUBPAGELINK' );
		$magicWords['LANDINGPREFIXED'] = array( 1, 'MÅLPREFIKSET', 'LANDINGPREFIXED' );
		$magicWords['LANDINGPREFIXEDLINK'] = array( 1, 'MÅLPREFIKSETLENKE', 'LANDINGPREFIXEDLINK' );
		$magicWords['LANDINGUSER'] = array( 1, 'MÅLBRUKER', 'LANDINGUSER' );
		$magicWords['LANDINGUSERLINK'] = array( 1, 'MÅLBRUKERLENKE', 'LANDINGUSERLINK' );
		$magicWords['LANDINGREALUSER'] = array( 1, 'MÅLRETTBRUKER', 'LANDINGREALUSER' );
		$magicWords['LANDINGREALUSERLINK'] = array( 1, 'MÅLRETTBRUKERLENKE', 'LANDINGREALUSERLINK' );
		break;
		
	# Norwegian (nynorsk) and default mapping
	case 'nn':
		$magicWords['LANDINGPAGE'] = array( 1, 'MÅLSIDE', 'LANDINGPAGE' );
		$magicWords['LANDINGPAGELINK'] = array( 1, 'MÅLSIDELEKKJE', 'LANDINGPAGELINK' );
		$magicWords['LANDINGSUBPAGE'] = array( 1, 'MÅLUNDERSIDE', 'LANDINGSUBPAGE' );
		$magicWords['LANDINGSUBPAGELINK'] = array( 1, 'MÅLUNDERSIDELEKKJE', 'LANDINGSUBPAGELINK' );
		$magicWords['LANDINGPREFIXED'] = array( 1, 'MÅLPREFIKSET', 'LANDINGPREFIXED' );
		$magicWords['LANDINGPREFIXEDLINK'] = array( 1, 'MÅLPREFIKSETLEKKJE', 'LANDINGPREFIXEDLINK' );
		$magicWords['LANDINGUSER'] = array( 1, 'MÅLBRUKAR', 'LANDINGUSER' );
		$magicWords['LANDINGUSERLINK'] = array( 1, 'MÅLBRUKARLEKKJE', 'LANDINGUSERLINK' );
		$magicWords['LANDINGREALUSER'] = array( 1, 'MÅLRETTBRUKAR', 'LANDINGREALUSER' );
		$magicWords['LANDINGREALUSERLINK'] = array( 1, 'MÅLRETTBRUKARLEKKJE', 'LANDINGREALUSERLINK' );
		break;
		
	# Default mapping
    	default:
		$magicWords['LANDINGPAGE'] = array( 1, 'LANDINGPAGE' );
		$magicWords['LANDINGPAGELINK'] = array( 1, 'LANDINGPAGELINK' );
		$magicWords['LANDINGSUBPAGE'] = array( 1, 'LANDINGSUBPAGE' );
		$magicWords['LANDINGSUBPAGELINK'] = array( 1, 'LANDINGSUBPAGELINK' );
		$magicWords['LANDINGPREFIXED'] = array( 1, 'LANDINGPREFIXED' );
		$magicWords['LANDINGPREFIXEDLINK'] = array( 1, 'LANDINGPREFIXEDLINK' );
		$magicWords['LANDINGUSER'] = array( 1, 'LANDINGUSER' );
		$magicWords['LANDINGUSERLINK'] = array( 1, 'LANDINGUSERLINK' );
		$magicWords['LANDINGREALUSER'] = array( 1, 'LANDINGREALUSER' );
		$magicWords['LANDINGREALUSERLINK'] = array( 1, 'LANDINGREALUSERLINK' );
	}
	
	#tell MediaWiki to go on to the next hook
	return true;
}

#----------------------------------------------------------------------------
#    Constants
#----------------------------------------------------------------------------

// Content
define( 'LANDING_TARGET', 0x1 );
define( 'LANDING_LINK', 0x2 );
define( 'LANDING_CONTENT', 0xf );

// Type
define( 'LANDING_PAGE', 0x010 );
define( 'LANDING_SUBPAGE', 0x020 );
define( 'LANDING_PREFIXED', 0x040 );
define( 'LANDING_USER', 0x080 );
define( 'LANDING_REALUSER', 0x100 );

// Masks
define( 'LANDING_MASK', 0xff0 );
define( 'LANDING_USERMASK', 0x180 );

#----------------------------------------------------------------------------
#    Rendering
#----------------------------------------------------------------------------

// Unwind the redirects
function wfLandingPageUnwind( &$parser, &$title1 ) {
	if (!$title1) {
		throw new Exception( 'none' );
	}
	$lc = LinkCache::singleton();
	$pdbk = $title1->getPrefixedDBkey();
	if ( 0 != ( $id = $lc->getGoodLinkID( $pdbk ) ) ) {
		$parser->mOutput->addLink( $title1, $id );
	} elseif ( $lc->isBadLink( $pdbk ) ) {
		$parser->mOutput->addLink( $title1, 0 );
		throw new Exception( $title1->getPrefixedText() );
	} else {
		$id = $title1->getArticleID();
		$parser->mOutput->addLink( $title1, $id );
		if (!$id) {
			throw new Exception( $title1->getPrefixedText() );
		}
	}
	$title2 = Article::newFromId($id)->followRedirect();
	if (!$title2)
		return $title1;
	$pdbk = $title2->getPrefixedDBkey();
	if ( 0 != ( $id = $lc->getGoodLinkID( $pdbk ) ) ) {
		$parser->mOutput->addLink( $title2, $id );
	} elseif ( $lc->isBadLink( $pdbk ) ) {
		$parser->mOutput->addLink( $title2, 0 );
		throw new Exception( $title2->getPrefixedText() );
	} else {
		$id = $title2->getArticleID();
		$parser->mOutput->addLink( $title2, $id );
		if (!$id) {
			throw new Exception( $title2->getPrefixedText() );
		}
	}
	return $title2;
}

// Processes the general parser function.
function wfRenderLandingPage( &$parser, $argv ) {
	$a = func_get_args();
	array_shift($a);
	$source = Title::newFromText(htmlspecialchars(array_shift($a)));
	$bits = array_pop($a);
	$alt = array_shift($a);
	try {
		$target = wfLandingPageUnwind( &$parser, Title::newFromText(htmlspecialchars($source)));
	}
	catch ( Exception $e ) {
		if ($alt)
			return $alt;
		else
			return wfMsg( 'landing-page-unknown', $e->getMessage() );
	}
	// there should also be a conditional landing
	if ($bits & LANDING_USERMASK) {
		if ( $target->getNamespace() != NS_USER ) {
			// this should be catched earlier
			if ($alt)
				return $alt;
			else
				return wfMsg( 'landing-namespace-unknown', $target->getPrefixedText() );
		}
		$id = User::newFromName( $target->getBaseText() );
		if ( !$id ) {
			if ($alt)
				return $alt;
			else
				return wfMsg( 'landing-user-unknown', $target->getBaseText() );
		}
	}
	$title = '';
	switch ($bits & LANDING_MASK) {
	case LANDING_PAGE :
		$title = $target->getBaseText();
		break;
	case LANDING_SUBPAGE :
		$title = $target->getSubPageText();
		break;
	case LANDING_PREFIXED :
		$title = $target->getPrefixedText();
		break;
	case LANDING_USER :
		$title = $id->getName();
		break;
	case LANDING_REALUSER :
		$title = $id->getRealname();
		break;
	default :
		if ($alt)
			return $alt;
		else
			return wfMsg( 'landing-type-unknown' );
	}
	if (($bits & LANDING_CONTENT) == LANDING_TARGET)
		return $parser->insertStripItem( $title, $parser->mStripState );
	elseif (($bits & LANDING_CONTENT) == LANDING_LINK)
		return $parser->insertStripItem( $parser->makeKnownLinkHolder( $source, $title ), $parser->mStripState );
	if ($alt)
		return $alt;
	else
		return wfMsg( 'landing-content-unknown', $bits & LANDING_CONTENT );
}

// Make our own array push
function wfLandingPush( &$a, $v ) {
	array_push($a, $v);
	return $a;
}

// Processes the parser callbacks
function wfRenderLandingPage_LANDINGPAGE( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_PAGE|LANDING_TARGET ) );
}

function wfRenderLandingPage_LANDINGPAGELINK( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_PAGE|LANDING_LINK ) );
}

function wfRenderLandingPage_LANDINGSUBPAGE( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_SUBPAGE|LANDING_TARGET ) );
}

function wfRenderLandingPage_LANDINGSUBPAGELINK( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_SUBPAGE|LANDING_LINK ) );
}

function wfRenderLandingPage_LANDINGPREFIXED( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_PREFIXED|LANDING_TARGET ) );
}

function wfRenderLandingPage_LANDINGPREFIXEDLINK( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_PREFIXED|LANDING_LINK ) );
}

function wfRenderLandingPage_LANDINGUSER( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_USER|LANDING_TARGET ) );
}

function wfRenderLandingPage_LANDINGUSERLINK( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_USER|LANDING_LINK ) );
}

function wfRenderLandingPage_LANDINGREALUSER( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_REALUSER|LANDING_TARGET ) );
}

function wfRenderLandingPage_LANDINGREALUSERLINK( &$parser, $argv ) {
	$a = func_get_args();
	return call_user_func_array( 'wfRenderLandingPage', wfLandingPush( $a, LANDING_REALUSER|LANDING_LINK ) );
}