Extension:NamespaceManager
From MediaWiki.org
|
NamespaceManager Release status: beta |
|
|---|---|
| Implementation | User interface |
| Description | |
| Author(s) | Jean-Lou Dupont (jldupont Talk) |
| Version | See SVN ($Id: NamespaceManager.php 705 2007-08-20 15:16:39Z jeanlou.dupont $) |
| MediaWiki | tested on 1.10 but probably works with a earlier versions |
| Download | SVN |
| Hooks used | |
Contents |
[edit] Purpose
Base class for 'Namespace Manager' extensions i.e. extensions that provide services under a specific namespace.
[edit] NOTE
This file isn't an extension per-se but rather a required class for other extensions e.g. Extension:ExtensionManager.
[edit] Features
- Automatically sets up the declared hooks of the derived class of 'NamespaceManager'
- Provides easy registration of 'messages'
- Provides easy registration of log related global variables
- Reports the number of registered namespace name
[edit] Dependancy
None.
[edit] Installation
To install independantly from BizzWiki:
- Download 'NamespaceManager.php' and place it in '/extensions/NamespaceManager/'
- Apply the following changes to 'LocalSettings.php':
require('extensions/NamespaceManager/NamespaceManager.php');
[edit] History
[edit] See Also
This extension is part of the BizzWiki Platform.
[edit] Code
<?php /* */ $wgExtensionCredits[NamespaceManagers::thisType][] = array( 'name' => NamespaceManagers::thisName, 'version' => NamespaceManagers::getRevisionId( '$Id: NamespaceManager.php 705 2007-08-20 15:16:39Z jeanlou.dupont $'), 'author' => 'Jean-Lou Dupont', 'description' => 'Provides a base class for namespace manager extensions. ', 'url' => NamespaceManagers::getFullUrl(__FILE__), ); require_once($IP.'/includes/Article.php'); /** All namespace managers should derive from this class. */ abstract class NamespaceManager extends Article { static $hookList = array(); // the namespace index in which the derived // class operates ... shortcut for convenience. var $ns; public function __construct( &$title ) { self::setupHooks(); parent::__construct( $title ); } /** Automatically sets up the declared hooks. */ protected static function setupHooks() { global $wgHooks; foreach ( self::$hookList as $index => $hookName) if ( method_exists( $this, 'h'.$hookName ) ) $wgHooks[$hookName][] = array( &$this, 'h'.$hookName ); } /** The view method will most probably need to be overriden Handler for the default action i.e. 'action=view' */ public function view() { echo __METHOD__.": must override this method."; } /** Handler for 'action=submit' */ public function submit() { echo __METHOD__.": must override this method."; } /** Handler for 'action=edit' */ public function edit() { echo __METHOD__.": must override this method."; } public function delete() { echo __METHOD__.": must override this method."; } public function watch() { echo __METHOD__.": must override this method."; } public function unwatch() { echo __METHOD__.": must override this method."; } public function protect() { echo __METHOD__.": must override this method."; } public function unprotect() { echo __METHOD__.": must override this method."; } public function revert() { echo __METHOD__.": must override this method."; } public function rollback() { echo __METHOD__.": must override this method."; } public function info() { echo __METHOD__.": must override this method."; } public function markpatrolled() { echo __METHOD__.": must override this method."; } public function render() { echo __METHOD__.": must override this method."; } public function deletetrackback() { echo __METHOD__.": must override this method."; } /** Catch-all */ public function __call( $method, $args ) { global $wgOut; $wgOut->showErrorPage( 'nosuchaction', 'nosuchactiontext' ); } protected function doPermissionError( &$titleObj, &$titleMessageId, &$messageId, &$subtitleMessageId = null ) { global $wgUser, $wgOut; $skin = $wgUser->getSkin(); $wgOut->setPageTitle( wfMsg( $titleMessageId ) ); if ($subtitleMessageId !== null) $wgOut->setSubtitle( wfMsg( $subTitleMessageId, $skin->makeKnownLinkObj( $titleObj ) ) ); $wgOut->addWikiText( wfMsg( $messageId ) ); } } // end class declaration // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% class NamespaceManagers { const thisType = 'other'; const thisName = 'NamespaceManagers'; static $list = array(); static $instanceList = array(); static $msgList = array(); static $logList = array(); /** Only 1 handler can be registered by Namespace. */ public static function register( $ns, $classe, $classfile ) { self::$list[$ns] = array( 'ns' => $ns, 'class' => $classe, 'file' => $classfile ); } public static function getList() { return self::$list; } public static function getMsgList() { return self::$msgList; } public static function getLogList() { return self::$logList; } /** Called during the initialization phase for extensions. */ public static function setupLogging( ) { if (empty( self::$logList )) return; foreach( self::$logList as $logtype => &$actions ) { # Add a new log type global $wgLogTypes, $wgLogNames, $wgLogHeaders, $wgLogActions; $wgLogTypes[] = $logtype; $wgLogNames [$logtype] = $logtype.'logpage'; $wgLogHeaders[$logtype] = $logtype.'logpagetext'; if (!empty( $actions )) foreach( $actions as $action ) $wgLogActions[$logtype.'/'.$action] = $logtype.'-'.$action.'-entry'; } } /** Each registered derived classes add their logging related variables through here. An extension's i18n file would call this function to register any logging functionality related global variables. */ public static function addLog( $log ) { self::$logList = array_merge( self::$logList, $log ); } /** Called during the initialization phase for extensions. */ public static function setupMessages( ) { global $wgMessageCache; foreach( self::$msgList as $key => $value ) $wgMessageCache->addMessages( self::$msgList[$key], $key ); } /** Each registered derived classes add their 'messages' An extension's i18n file would call this function to register any messages */ public static function addMessages( &$msg ) { self::$msgList = array_merge( self::$msgList, $msg ); } /** Setup the initialization phase for this extension */ public static function setup() { global $wgExtensionFunctions; # $wgExtensionFunctions[] = __CLASS__.'::setup'; // PHP <v5.2.2 issues a warning on this one. $wgExtensionFunctions[] = create_function( '', 'return '.__CLASS__.'::init();' ); } public static function init() { global $wgHooks; $wgHooks['ArticleFromTitle'][] = 'NamespaceManagers::hArticleFromTitle'; $wgHooks['CustomEditor'][] = 'NamespaceManagers::hCustomEditor'; $wgHooks['SpecialVersionExtensionTypes'][] = 'NamespaceManagers::hSpecialVersionExtensionTypes'; global $wgAutoloadClasses; if (!empty( self::$list )) foreach( self::$list as $index => &$e ) $wgAutoloadClasses[$e['class']] = $e['file']; self::setupMessages(); self::setupLogging(); } /** Reports the status of this extension in the [[Special:Version]] page. */ public function hSpecialVersionExtensionTypes( &$sp, &$extensionTypes ) { #self::loadAllRegisteredClasses(); global $wgExtensionCredits; $result = 'There are '.count(self::$list)." namespace managers registered."; // Add list of managed extensions // add other checks here. foreach ( $wgExtensionCredits[self::thisType] as $index => &$el ) if (isset($el['name'])) if ($el['name']==self::thisName) $el['description'] .= $result; return true; // continue hook-chain. } private static function loadAllRegisteredClasses() { if (empty(self::$list)) return; foreach( self::$list as &$e ) { $classe = $e['class']; self::$instanceList[] = new $classe(); } } /** This is the main hook of the extension: it intercepts the process flow right at the article creation phase in order to instantiate a specific class for the namespace in focus. Of course, each namespace must be registered through the 'register' function in order for this hook to function properly. */ public static function hArticleFromTitle( &$title, &$article ) { $ns = $title->getNamespace(); // Let MW handle these ones. if (NS_MEDIA==$ns || NS_CATEGORY==$ns || NS_IMAGE==$ns) return true; // Look-up if we have a registered manager for the // current requested namespace. if (!array_key_exists( $ns, self::$list )) return true; // At this point, we have concluded we have a registered manager $classe = self::$list[$ns]['class']; $article = new $classe( $title ); $article->ns = $ns; return true; } /** We also need to trap this event as our namespace manager will most probably need to provide a special 'edit form' */ public function hCustomEditor( $article, $user ) { if (!( $article instanceof NamespaceManager )) return true; global $action; if ( 'submit' == $action ) { $article->submit(); return false; } if ( 'edit' == $action ) { $article->edit(); return false; } return true; } // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // GENERIC HELPER FUNCTIONS // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% static function getRevisionId( $svnId=null ) { // fixed annoying warning about undefined offset. if ( $svnId === null || $svnId == ('$'.'Id'.'$' /* fool SVN */) ) return null; // e.g. $Id: NamespaceManager.php 705 2007-08-20 15:16:39Z jeanlou.dupont $ $data = explode( ' ', $svnId ); return $data[2]; } static function getFullUrl( $filename ) { return 'http://www.bizzwiki.org/index.php?title=Filesystem:'.self::getRelativePath( $filename ); } static function getRelativePath( $filename ) { global $IP; $relPath = str_replace( $IP, '', $filename ); return str_replace( '\\', '/', $relPath ); // at least windows & *nix agree on this! } } // end class declaration NamespaceManagers::setup(); // List up-to-date with MW 1.10 SVN 21828 NamespaceManager::$hookList = array( 'ArticlePageDataBefore', 'ArticlePageDataAfter', 'ArticleAfterFetchContent', 'ArticleViewRedirect', 'ArticleViewHeader', 'ArticlePurge', 'ArticleSave', // public function hArticleSave ( &$article, &$user, &$text, $summary, $minor, $dontcare1, $dontcare2, &$flags ) {} 'ArticleInsertComplete', 'ArticleSaveComplete', // public function hArticleSaveComplete( &$article, &$user, &$text, $summary, $minor, $dontcare1, $dontcare2, &$flags ) {} 'MarkPatrolled', 'MarkPatrolledComplete', 'WatchArticle', 'WatchArticleComplete', 'UnwatchArticle', 'UnwatchArticleComplete', 'ArticleProtect', 'ArticleProtectComplete', 'ArticleDelete', 'ArticleDeleteComplete', 'ArticleEditUpdatesDeleteFromRecentchanges', 'ArticleEditUpdateNewTalk', 'DisplayOldSubtitle', 'IsFileCacheable', 'CategoryPageView', 'FetchChangesList', 'DiffViewHeader', 'AlternateEdit', 'EditFormPreloadText', // public function hEditFormPreloadText( &$textbox, &$title ) {} 'EditPage::attemptSave', 'EditFilter', 'EditPage::showEditForm:initial', 'EditPage::showEditForm:fields', 'SiteNoticeBefore', 'SiteNoticeAfter', 'FileUpload', 'BadImage', 'MagicWordMagicWords', 'MagicWordwgVariableIDs', 'MathAfterTexvc', 'MessagesPreLoad', 'LoadAllMessages', 'OutputPageParserOutput', 'OutputPageBeforeHTML', 'AjaxAddScript', 'PageHistoryBeforeList', 'PageHistoryLineEnding', 'ParserClearState', 'ParserBeforeStrip', 'ParserAfterStrip', 'ParserBeforeTidy', 'ParserAfterTidy', // public function hParserAfterTidy( &$parser, &$text ) {} 'ParserBeforeInternalParse', 'InternalParseBeforeLinks', 'ParserGetVariableValueVarCache', 'ParserGetVariableValueTs', 'ParserGetVariableValueSwitch', 'IsTrustedProxy', 'wgQueryPages', 'RawPageViewBeforeOutput', 'RecentChange_save', 'SearchUpdate', 'AuthPluginSetup', 'LogPageValidTypes', 'LogPageLogName', 'LogPageLogHeader', 'LogPageActionText', 'SkinTemplateTabs', 'BeforePageDisplay', 'SkinTemplateOutputPageBeforeExec', 'PersonalUrls', 'SkinTemplatePreventOtherActiveTabs', 'SkinTemplateTabs', 'SkinTemplateBuildContentActionUrlsAfterSpecialPage', 'SkinTemplateContentActions', 'SkinTemplateBuildNavUrlsNav_urlsAfterPermalink', 'SkinTemplateSetupPageCss', 'BlockIp', 'BlockIpComplete', 'BookInformation', 'SpecialContributionsBeforeMainOutput', 'EmailUser', 'EmailUserComplete', 'SpecialMovepageAfterMove', 'SpecialPage_initList', 'SpecialPageExecuteBeforeHeader', 'SpecialPageExecuteBeforePage', 'SpecialPageExecuteAfterPage', 'PreferencesUserInformationPanel', 'SpecialSearchNogomatch', 'ArticleUndelete', 'UndeleteShowRevision', 'UploadForm:BeforeProcessing', 'UploadVerification', 'UploadComplete', 'UploadForm:initial', 'AddNewAccount', 'AbortNewAccount', 'UserLoginComplete', 'UserCreateForm', 'UserLoginForm', 'UserLogout', 'UserLogoutComplete', 'UserRights', 'SpecialVersionExtensionTypes', 'AutoAuthenticate', 'GetFullURL', 'GetLocalURL', 'GetInternalURL', 'userCan', 'TitleMoveComplete', 'isValidPassword', 'UserToggles', 'GetBlockedStatus', 'PingLimiter', 'UserRetrieveNewTalks', 'UserClearNewTalkNotification', 'PageRenderingHash', 'EmailConfirmed', 'ArticleFromTitle', 'CustomEditor', 'UnknownAction', 'LanguageGetMagic', 'LangugeGetSpecialPageAliases', 'MonoBookTemplateToolboxEnd', 'SkinTemplateSetupPageCss', 'SkinTemplatePreventOtherActiveTabs', ); //

