2006-07-26 17:12:30 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Setup and Hooks for the CategoryTree extension, an AJAX based gadget
|
|
|
|
* to display the category structure of a wiki
|
|
|
|
*
|
|
|
|
* @package MediaWiki
|
|
|
|
* @subpackage Extensions
|
|
|
|
* @author Daniel Kinzler <duesentrieb@brightbyte.de>
|
|
|
|
* @copyright © 2006 Daniel Kinzler
|
|
|
|
* @licence GNU General Public Licence 2.0 or later
|
|
|
|
*/
|
|
|
|
|
|
|
|
if( !defined( 'MEDIAWIKI' ) ) {
|
|
|
|
echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" );
|
|
|
|
die( 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Constants for use with efCategoryTreeRenderChildren,
|
|
|
|
* defining what should be shown in the tree
|
|
|
|
*/
|
|
|
|
define('CT_MODE_CATEGORIES', 0);
|
|
|
|
define('CT_MODE_PAGES', 10);
|
|
|
|
define('CT_MODE_ALL', 20);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Abort if AJAX is not enabled
|
|
|
|
**/
|
|
|
|
if ( !$wgUseAjax ) {
|
2006-07-30 10:49:31 +00:00
|
|
|
#NOTE: GlobalFunctions is not yet loaded, so use standard API only.
|
|
|
|
trigger_error( 'CategoryTree: Ajax is not enabled, aborting extension setup.', E_USER_WARNING );
|
2006-07-26 17:12:30 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Options:
|
|
|
|
*
|
|
|
|
* $wgCategoryTreeMaxChildren - maximum number of children shown in a tree node. Default is 200
|
|
|
|
* $wgCategoryTreeAllowTag - enable <categorytree> tag. Default is true.
|
2006-07-28 16:07:55 +00:00
|
|
|
* $wgCategoryTreeDynamicTag - loads the first level of the tree in a <categorytag> dynamically.
|
|
|
|
* This way, the cache does not need to be disabled. Default is false.
|
2006-07-26 17:12:30 +00:00
|
|
|
* $wgCategoryTreeDisableCache - disabled the parser cache for pages with a <categorytree> tag. Default is true.
|
2006-08-23 19:23:17 +00:00
|
|
|
* $wgCategoryTreeUseCache - enable HTTP cache for anon users. Default is false.
|
2006-07-26 17:12:30 +00:00
|
|
|
*/
|
|
|
|
if ( !isset( $wgCategoryTreeMaxChildren ) ) $wgCategoryTreeMaxChildren = 200;
|
|
|
|
if ( !isset( $wgCategoryTreeAllowTag ) ) $wgCategoryTreeAllowTag = true;
|
|
|
|
if ( !isset( $wgCategoryTreeDisableCache ) ) $wgCategoryTreeDisableCache = true;
|
2006-07-28 16:07:55 +00:00
|
|
|
if ( !isset( $wgCategoryTreeDynamicTag ) ) $wgCategoryTreeDynamicTag = false;
|
2006-08-23 19:23:17 +00:00
|
|
|
if ( !isset( $wgCategoryTreeHTTPCache ) ) $wgCategoryTreeHTTPCache = false;
|
2006-07-26 17:12:30 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Register extension setup hook and credits
|
|
|
|
*/
|
|
|
|
$wgExtensionFunctions[] = 'efCategoryTree';
|
2006-07-28 16:07:55 +00:00
|
|
|
$wgExtensionCredits['specialpage'][] = array( 'name' => 'CategoryTree', 'author' => 'Daniel Kinzler', 'url' => 'http://meta.wikimedia.org/wiki/CategoryTree_extension' );
|
|
|
|
$wgExtensionCredits['parserhook'][] = array( 'name' => 'CategoryTree', 'author' => 'Daniel Kinzler', 'url' => 'http://meta.wikimedia.org/wiki/CategoryTree_extension' );
|
2006-07-26 17:12:30 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Register the special page
|
|
|
|
*/
|
|
|
|
$wgAutoloadClasses['CategoryTree'] = dirname( __FILE__ ) . '/CategoryTreePage.php';
|
|
|
|
$wgSpecialPages['CategoryTree'] = 'CategoryTree';
|
|
|
|
$wgHooks['SkinTemplateTabs'][] = 'efCategoryTreeInstallTabs';
|
2006-07-29 09:18:34 +00:00
|
|
|
#$wgHooks['OutputPageBeforeHTML'][] = 'efCategoryTreeHeadHook';
|
2006-07-26 17:12:30 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* register Ajax function
|
|
|
|
*/
|
|
|
|
$wgAjaxExportList[] = 'efCategoryTreeAjaxWrapper';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook it up
|
|
|
|
*/
|
|
|
|
function efCategoryTree() {
|
2006-07-29 09:18:34 +00:00
|
|
|
global $wgParser, $wgOut, $wgCategoryTreeAllowTag;
|
|
|
|
global $wgJsMimeType, $wgScriptPath;
|
2006-07-26 17:12:30 +00:00
|
|
|
|
|
|
|
if ( $wgCategoryTreeAllowTag ) $wgParser->setHook( 'categorytree' , 'efCategoryTreeParserHook' );
|
2006-07-29 09:18:34 +00:00
|
|
|
|
|
|
|
#TODO: injecting scripts should be done on demand, by "somehow" using the ParserOutput
|
|
|
|
|
|
|
|
#register css file for CategoryTree
|
|
|
|
$wgOut->addLink( array( 'rel' => 'stylesheet', 'type' => 'text/css', 'href' => $wgScriptPath . '/extensions/CategoryTree/CategoryTree.css' ) );
|
|
|
|
|
|
|
|
#register main js file for CategoryTree
|
|
|
|
$wgOut->addScript( "<script type=\"{$wgJsMimeType}\" src=\"{$wgScriptPath}/extensions/CategoryTree/CategoryTree.js\"></script>\n" );
|
2006-07-26 17:12:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Entry point for Ajax, registered in $wgAjaxExportList.
|
|
|
|
* This loads CategoryTreeFunctions.php and calls efCategoryTreeAjax()
|
|
|
|
*/
|
|
|
|
function efCategoryTreeAjaxWrapper( $category, $mode = CT_MODE_CATEGORIES ) {
|
2006-08-23 19:23:17 +00:00
|
|
|
global $wgAjaxCachePolicy, $wgCategoryTreeHTTPCache, $wgSquidMaxAge, $wgUseSquid;
|
|
|
|
|
|
|
|
if ( $wgCategoryTreeHTTPCache && $wgSquidMaxAge && $wgUseSquid ) {
|
|
|
|
$wgAjaxCachePolicy->setPolicy( $wgSquidMaxAge );
|
|
|
|
$wgAjaxCachePolicy->setVary( 'Accept-Encoding, Cookie' ); #cache for anons only
|
|
|
|
#TODO: purge the squid cache when a category page is invalidated
|
|
|
|
}
|
|
|
|
|
2006-07-26 23:11:23 +00:00
|
|
|
require_once( dirname( __FILE__ ) . '/CategoryTreeFunctions.php' );
|
2006-07-26 17:12:30 +00:00
|
|
|
|
2006-07-29 09:18:34 +00:00
|
|
|
efInjectCategoryTreeMessages();
|
|
|
|
|
2006-07-26 17:12:30 +00:00
|
|
|
return efCategoryTreeAjax( $category, $mode );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Entry point for the <categorytree> tag parser hook.
|
|
|
|
* This loads CategoryTreeFunctions.php and calls efCategoryTreeTag()
|
|
|
|
*/
|
2006-08-23 19:23:17 +00:00
|
|
|
function efCategoryTreeParserHook( $cat, $argv, &$parser ) {
|
|
|
|
#$parser->mOutput->mCategoryTreeTag = true; #HACK: flag for use by efCategoryTreeHeadHook
|
2006-07-29 09:18:34 +00:00
|
|
|
|
2006-08-23 19:23:17 +00:00
|
|
|
static $initialized = false;
|
2006-07-26 23:11:23 +00:00
|
|
|
|
2006-07-26 17:12:30 +00:00
|
|
|
$style= @$argv[ 'style' ];
|
|
|
|
|
|
|
|
$mode= @$argv[ 'mode' ];
|
|
|
|
if ( $mode !== NULL ) {
|
|
|
|
$mode= trim( strtolower( $mode ) );
|
|
|
|
|
|
|
|
if ( $mode == 'all' ) $mode = CT_MODE_ALL;
|
|
|
|
else if ( $mode == 'pages' ) $mode = CT_MODE_PAGES;
|
|
|
|
else if ( $mode == 'categories' ) $mode = CT_MODE_CATEGORIES;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$mode = CT_MODE_CATEGORIES;
|
|
|
|
}
|
|
|
|
|
|
|
|
$hideroot = @$argv[ 'hideroot' ];
|
|
|
|
if ( $hideroot !== NULL ) {
|
|
|
|
$hideroot = trim( strtolower( $hideroot ) );
|
|
|
|
|
|
|
|
if ( $hideroot === '1' || $hideroot === 'yes' || $hideroot === 'on' || $hideroot === 'true' ) $hideroot = true;
|
|
|
|
else if ( $hideroot === '0' || $hideroot === 'no' || $hideroot === 'off' || $hideroot === 'false' ) $hideroot = false;
|
|
|
|
}
|
2006-08-23 19:23:17 +00:00
|
|
|
|
|
|
|
if ( !$initialized ) {
|
|
|
|
require_once( dirname( __FILE__ ) . '/CategoryTreeFunctions.php' );
|
|
|
|
|
2006-07-29 09:18:34 +00:00
|
|
|
efInjectCategoryTreeMessages();
|
2006-08-23 19:23:17 +00:00
|
|
|
|
|
|
|
#HACK for inlining JS messages "on demand". Putting them into the head would be nicer,
|
|
|
|
# but that would require some changes to ParserOutput to deal with the parser cache
|
2006-07-29 09:18:34 +00:00
|
|
|
$m = efCategoryTreeGetJsMessages();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$m = '';
|
|
|
|
}
|
2006-07-26 17:12:30 +00:00
|
|
|
|
2006-08-23 19:23:17 +00:00
|
|
|
$initialized = true;
|
|
|
|
|
|
|
|
return $m . efCategoryTreeTag( $parser, $cat, $mode, $hideroot, $style );
|
2006-07-26 17:12:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook callback that installs a tab for CategoryTree on Category pages
|
|
|
|
*/
|
|
|
|
function efCategoryTreeInstallTabs( &$skin, &$content_actions ) {
|
|
|
|
global $wgTitle;
|
|
|
|
|
|
|
|
if ( $wgTitle->getNamespace() != NS_CATEGORY ) return true;
|
|
|
|
|
|
|
|
$special = Title::makeTitle( NS_SPECIAL, 'CategoryTree' );
|
|
|
|
|
|
|
|
efInjectCategoryTreeMessages();
|
|
|
|
|
|
|
|
$content_actions['categorytree'] = array(
|
|
|
|
'class' => false,
|
|
|
|
'text' => wfMsgHTML( 'categorytree-tab' ),
|
|
|
|
'href' => $special->getLocalUrl() . '/' . $wgTitle->getPartialURL() );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2006-07-29 09:18:34 +00:00
|
|
|
/**
|
|
|
|
* Hook callback that injects messages and things into the <head> tag
|
|
|
|
* Does nothing if $parserOutput->mCategoryTreeTag is not set
|
|
|
|
*/
|
|
|
|
/* function efCategoryTreeHeadHook( &$parserOutput, &$text ) {
|
|
|
|
if ( ! @$parserOutput->mCategoryTreeTag ) return;
|
|
|
|
|
|
|
|
require_once( dirname( __FILE__ ) . '/CategoryTreeFunctions.php' );
|
|
|
|
|
|
|
|
efInjectCategoryTreeMessages();
|
|
|
|
efCategoryTreeHeader();
|
|
|
|
} */
|
|
|
|
|
2006-07-26 17:12:30 +00:00
|
|
|
/**
|
|
|
|
* inject messages used by CategoryTree into the message cache
|
|
|
|
*/
|
|
|
|
function efInjectCategoryTreeMessages() {
|
2006-07-29 09:18:34 +00:00
|
|
|
global $wgMessageCache;
|
2006-07-26 17:12:30 +00:00
|
|
|
|
2006-07-29 09:18:34 +00:00
|
|
|
static $done = false;
|
|
|
|
if ( $done ) return;
|
|
|
|
else $done = true;
|
|
|
|
|
2006-07-26 17:12:30 +00:00
|
|
|
$msg = efLoadCategoryTreeMessages();
|
|
|
|
$wgMessageCache->addMessages( $msg );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* load the CategoryTree internationalization file
|
|
|
|
*/
|
|
|
|
function efLoadCategoryTreeMessages() {
|
2006-07-29 09:18:34 +00:00
|
|
|
global $wgLang;
|
2006-07-26 17:12:30 +00:00
|
|
|
|
|
|
|
$messages= array();
|
|
|
|
|
|
|
|
$f= dirname( __FILE__ ) . '/CategoryTree.i18n.php';
|
|
|
|
include( $f );
|
|
|
|
|
2006-07-29 09:18:34 +00:00
|
|
|
$f= dirname( __FILE__ ) . '/CategoryTree.i18n.' . $wgLang->getCode() . '.php';
|
2006-07-26 17:12:30 +00:00
|
|
|
if ( file_exists( $f ) ) include( $f );
|
|
|
|
|
|
|
|
return $messages;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates a Title object from a user provided (and thus unsafe) string
|
|
|
|
*/
|
|
|
|
function & efCategoryTreeMakeTitle( $title ) {
|
|
|
|
global $wgContLang, $wgCanonicalNamespaceNames;
|
|
|
|
|
2006-08-11 23:36:53 +00:00
|
|
|
$title = trim($title);
|
|
|
|
|
|
|
|
if ( $title === NULL || $title === '' || $title === false ) {
|
|
|
|
$dummy = NULL; #php sucks
|
|
|
|
return $dummy;
|
|
|
|
}
|
|
|
|
|
2006-07-26 17:12:30 +00:00
|
|
|
#HACK to strip redundant namespace name
|
|
|
|
$title = preg_replace( '~^\s*(' . $wgCanonicalNamespaceNames[ NS_CATEGORY ] . '|' . $wgContLang->getNsText( NS_CATEGORY ) . ')\s*:\s*~i', '', $title );
|
|
|
|
|
|
|
|
$t = Title::makeTitleSafe( NS_CATEGORY, $title );
|
|
|
|
return $t;
|
|
|
|
}
|
|
|
|
|
2006-07-27 00:56:16 +00:00
|
|
|
?>
|