Extension:NamespaceManager

From MediaWiki.org

Jump to: navigation, search
Manual on MediaWiki Extensions
List of MediaWiki Extensions
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

ArticleFromTitle
CustomEditor
SpecialVersionExtensionTypes

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',
);
 
//
Personal tools