* @copyright Copyright (C) 2005-2007 Stephanie Amanda Stevens
* @copyright Copyright (C) 2007 SPQRobin
* @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
* Formatting improvements Stephen Kennedy, 2006.
*/
if ( !defined( 'MEDIAWIKI' ) ) {
die();
}
$wgExtensionCredits['specialpage'][] = array(
'path' => __FILE__,
'name' => 'SpecialNamespaces',
'url' => 'https://mediawiki.org/wiki/Extension:SpecialNamespaces',
'description' => 'Adds a [[Special:Namespaces|special page]] to view and edit the namespaces table',
'author' => array( 'Stephanie Amanda Stevens', 'SPQRobin', 'others' ),
'descriptionmsg' => 'namespaces-desc',
);
$dir = dirname( __FILE__ ) . '/';
$wgExtensionMessagesFiles['Namespaces'] = $dir . 'SpecialNamespaces.i18n.php';
$wgExtensionAliasesFiles['Namespaces'] = $dir . 'SpecialNamespaces.alias.php';
$wgSpecialPages['Namespaces'] = 'SpecialNamespaces';
$wgSpecialPageGroups['Namespaces'] = 'wiki';
$wgAutoloadClasses['SpecialNamespaces'] = $dir . 'SpecialNamespaces_body.php';
$wgAvailableRights[] = 'namespaces';
$wgGroupPermissions['sysop']['namespaces'] = true;
$wgLogTypes[] = 'namespaces';
$wgLogNames['namespaces'] = 'namespaces_logpagename';
$wgLogHeaders['namespaces'] = 'namespaces_logpagetext';
$wgLogActions['namespaces/namespaces'] = 'namespaces_logentry';
$wgLogActions['namespaces/ns_add'] = 'namespaces_log_added';
$wgLogActions['namespaces/ns_delete'] = 'namespaces_log_deleted';
$wgLogActions['namespaces/ns_edit'] = 'namespaces_log_edited';
# hook to retrieve $wgExtraNamespaces[...] from cached database table (namespace_names)
$wgHooks['CanonicalNamespaces'][] = 'fnNamespaceHook';
# hook for initial database table creation on MW 1.18+
$wgHooks['LoadExtensionSchemaUpdates'][] = 'fnNamespaceSchemaUpdates';
/**
* Database table creation (invoked in maintenance/update.php script)
*
* Installs a hook to call fnNamespaceCreateTables() to build an empty 'namespace_names' MySQL table.
* If the table already exists, this code does nothing.
*/
function fnNamespaceSchemaUpdates( DatabaseUpdater $updater ) {
$updater->addExtensionUpdate( array( 'fnNamespaceCreateTables' ) );
return true;
}
/**
* Create database table 'namespace_names' if it does not already exist (invoked from update.php)
*
* @param DatabaseUpdater $updater - the instance of update.php which initiated this installation process
* @return (no return value) - output table (if created) is sent to main database with status to console
*/
function fnNamespaceCreateTables( $updater ) {
global $wgDBtype;
$base = dirname( __FILE__ );
$db = $updater->getDB();
if ( $db->tableExists( 'namespace_names' ) ) {
$updater->output( "...namespace_names table already exists.\n" );
} else {
$sourcefile = $wgDBtype === 'postgres' ? '/namespace_names.pg.sql' : '/namespace_names.sql';
$db->sourceFile( dirname( __FILE__ ) . $sourcefile );
}
$updater->output( "...namespace_names table added.\n" );
}
/**
* Retrieve list of canonical namespaces from database table 'namespace_names'
* Global namespace lists $wgExtraNamespaces[] and $wgNamespaceAliases[] are updated as needed
*
* This is a MediaWiki hook function, which uses the 'CanonicalNamespaces' hook in MW 1.17+
* Use of memcached (where available) is necessary to avoid severe performance penalty for multiple db accesses
*
* @param array &$namespaces - the list of canonical namespaces retrieved from 'namespace_names' will be placed here
* @return boolean true at all times (as a MediaWiki hook must always return a value)
*/
function fnNamespaceHook ( array &$namespaces ) {
global $wgExtraNamespaces, $wgNamespaceAliases;
global $wgDBname, $wgMemc;
global $wgSitename, $wgMetaNamespace, $wgMetaNamespaceTalk;
if ( $wgExtraNamespaces == NULL ) {
$wgExtraNamespaces = array();
}
if ( $wgNamespaceAliases == NULL ) {
$wgNamespaceAliases = array();
}
$key = wfMemcKey( 'SpecialNamespaces', 'names' );
$cached = $wgMemc->get( $key );
if ( ( $cached == NULL ) || ( !is_array( $cached ) ) ) {
// if namespaces are not in memcache, retrieve them from main database
$dbr =& wfGetDB( DB_SLAVE );
$res = $dbr->select( 'namespace_names', '*' );
$numrows = $dbr->numRows( $res );
if ( $numrows > 0 )
while ( $s = $dbr->fetchObject( $res ) ) {
// for each namespace...
$nsindex = htmlspecialchars( $s->ns_id );
$nsname = htmlspecialchars( $s->ns_name );
$nscanonical = htmlspecialchars( $s->ns_canonical );
$nsdefault = htmlspecialchars( $s->ns_default );
$nsname = str_replace( ' ', '_', $nsname );
$nsname = str_replace( ':', '', $nsname );
// add the namespace (or namespace alias) to global configuration variables
if ( $nsdefault > 0 ) {
$wgExtraNamespaces[$nsindex] = $nsname;
if ( $nsindex == NS_PROJECT ) {
$wgSitename = $nsname;
$wgMetaNamespace = str_replace( ' ', '_', $nsname );
}
if ( $nsindex == NS_PROJECT_TALK ) {
$wgMetaNamespaceTalk = str_replace( ' ', '_', $nsname );
}
} else {
$wgNamespaceAliases[$nsname] = $nsindex;
}
// if canonical, add the namespace to list of canonical names in MW hook parameter
if ( $nscanonical > 0 ) {
$namespaces[$nsindex] = $nsname;
}
}
$dbr->freeResult( $res );
// store this info to memcache for re-use on subsequent page loads
$wgMemc->set ( $key, array(
'ns' => $namespaces,
'ens' => $wgExtraNamespaces,
'aka' => $wgNamespaceAliases,
'site' => $wgSitename,
'project' => $wgMetaNamespace,
'prjtalk' => $wgMetaNamespaceTalk
) );
} else {
// if data was retrieved from memcache, use it directly
$namespaces = $cached['ns'];
$wgExtraNamespaces = $cached['ens'];
$wgNamespaceAliases = $cached['aka'];
$wgSitename = $cached['site'];
$wgMetaNamespace = $cached['project'];
$wgMetaNamespaceTalk = $cached['prjtalk'];
}
return true;
}
SpecialNamespaces-1.0gerrit/SpecialNamespaces_body.php 0000644 0000000 0000000 00000031362 12136763515 0023271 0 ustar 00root root 0000000 0000000 delete( wfMemcKey( 'SpecialNamespaces', 'names' ) );
}
function execute( $par ) {
$admin = $this->getUser()->isAllowed( 'namespaces' );
$this->setHeaders();
$this->outputHeader();
if ( $admin ) {
$this->getOutput()->setPagetitle( wfMessage( 'namespaces' ) );
} else {
$this->getOutput()->setPagetitle( wfMessage( 'namespaces-title-norights' ) );
}
$req = $this->getRequest();
$action = $req->getVal( 'action', $par );
switch ( $action ) {
case "delete":
case "edit" :
case "add" :
if ( !$admin ) {
$this->getOutput()->permissionRequired( 'namespaces' );
return;
}
$this->showForm( $action );
break;
case "submit":
if ( !$admin ) {
$this->getOutput()->permissionRequired( 'namespaces' );
return;
}
if ( !$req->wasPosted() || !$this->getUser()->matchEditToken( $req->getVal( 'wpEditToken' ) ) ) {
$this->getOutput()->addWikiMsg( 'sessionfailure' );
return;
}
$this->doSubmit();
break;
default:
$this->showList( $admin );
break;
}
}
function showForm( $action ) {
$actionUrl = $this->getTitle()->getLocalURL( 'action=submit' );
$req = $this->getRequest();
$token = $this->getUser()->getEditToken();
$defaultreason = $req->getVal( 'wpNamespacesReason', wfMessage( 'namespaces_defaultreason' )->text() );
switch ( $action ) {
case "delete":
$nsid = $req->getVal( 'prefix' );
$nsoldname = $req->getVal( 'name' );
$button = wfMessage( 'delete' )->text();
$topmessage = wfMessage( 'namespaces_delquestion', $nsid )->text();
$deletingmessage = wfMessage( 'namespaces_deleting', $nsoldname )->text();
$reasonmessage = wfMessage( 'deletecomment' )->text();
$this->getOutput()->addHTML(
Xml::openElement( 'fieldset' ) .
Xml::element( 'legend', null, $topmessage ) .
Xml::openElement( 'form', array( 'id' => 'mw-namespaces-deleteform', 'method' => 'post', 'action' => $actionUrl ) ) .
Xml::openElement( 'table' ) .
"$deletingmessage |
" .
'' . Xml::label( $reasonmessage, 'mw-namespaces-deletereason' ) . ' | ' .
'' .
Xml::input( 'wpNamespacesReason', 60, $defaultreason, array( 'tabindex' => '1', 'id' => 'mw-namespaces-deletereason', 'maxlength' => '200' ) ) .
' |
' .
'' . Xml::submitButton( $button, array( 'id' => 'mw-namespaces-submit' ) ) .
Html::hidden( 'wpNamespacesID', $nsid ) .
Html::hidden( 'wpNamespacesOldName', $nsoldname ) .
Html::hidden( 'wpNamespacesAction', $action ) .
Html::hidden( 'wpEditToken', $token ) .
' |
' .
Xml::closeElement( 'table' ) .
Xml::closeElement( 'form' ) .
Xml::closeElement( 'fieldset' )
);
break;
case "edit" :
case "add" :
if ( $action == "edit" ) {
$nsid = $req->getVal( 'prefix' );
$nsoldname = $req->getVal( 'name' );
$dbr = wfGetDB( DB_SLAVE );
$row = $dbr->selectRow( 'namespace_names', '*', array( 'ns_name' => $nsoldname, 'ns_id' => $nsid ) );
if ( !$row ) {
$this->error( 'namespaces_editerror', $nsoldname );
return;
}
$nsid = '' . htmlspecialchars( $row->ns_id ) . '';
$defaultname = $row->ns_name;
$nsdefault = $row->ns_default;
$nscanonical = $row->ns_canonical;
$old = Html::hidden( 'wpNamespacesID', $row->ns_id );
$old .= Html::hidden( 'wpNamespacesOldName', $row->ns_name );
$topmessage = wfMessage( 'namespaces_edittext' )->parse();
$intromessage = wfMessage( 'namespaces_editintro' )->parse();
$button = wfMessage( 'edit' )->text();
} else {
$nsid = $req->getVal( 'wpNamespacesID' ) ? $req->getVal( 'wpNamespacesID' ) : $req->getVal( 'prefix' );
$nsid = Xml::input( 'wpNamespacesID', 20, $nsid, array( 'tabindex' => '1', 'id' => 'mw-namespaces-nsid', 'maxlength' => '20' ) );
$nsdefault = $req->getCheck( 'wpNamespacesDefault' );
$nscanonical = $req->getCheck( 'wpNamespacesCanonical' );
$old = '';
$defaultname = $req->getVal( 'wpNamespacesName' ) ? $req->getVal( 'wpNamespacesName' ) : wfMessage( 'namespaces_defaultname' )->text() ;
$topmessage = wfMessage( 'namespaces_addtext' )->parse();
$intromessage = wfMessage( 'namespaces_addintro' )->parse();
$button = wfMessage( 'namespaces_addbutton' )->text();
}
$nsidmessage = wfMessage( 'namespaces_nsid' )->parse();
$nsdefaultmessage = wfMessage( 'namespaces_default' )->text();
$nscanonicalmessage = wfMessage( 'namespaces_canonical' )->text();
$reasonmessage = wfMessage( 'namespaces_reasonfield' )->text();
$nsnamemessage = wfMessage( 'namespaces_nsname' )->text();
$this->getOutput()->addHTML(
Xml::openElement( 'fieldset' ) .
Xml::element( 'legend', null, $topmessage ) .
$intromessage .
Xml::openElement( 'form', array( 'id' => 'mw-namespaces-editform', 'method' => 'post', 'action' => $actionUrl ) ) .
Xml::openElement( 'table', array( 'id' => "mw-namespaces-$action" ) ) .
"$nsidmessage | $nsid |
" .
"" . Xml::label( $nsdefaultmessage, 'mw-namespaces-nsdefault' ) . ' | ' .
"" . Xml::check( 'wpNamespacesDefault', $nsdefault, array( 'id' => 'mw-namespaces-nsdefault' ) ) . ' |
' .
'' . Xml::label( $nscanonicalmessage, 'mw-namespaces-nscanonical' ) . ' | ' .
'' . Xml::check( 'wpNamespacesCanonical', $nscanonical, array( 'id' => 'mw-namespaces-nscanonical' ) ) . ' |
' .
'' . Xml::label( $nsnamemessage, 'mw-namespaces-nsname' ) . ' | ' .
'' . Xml::input( 'wpNamespacesName', 60, $defaultname, array( 'tabindex' => '1', 'maxlength' => '200', 'id' => 'mw-namespaces-nsname' ) ) . ' |
' .
'' . Xml::label( $reasonmessage, 'mw-namespaces-editreason' ) . ' | ' .
'' . Xml::input( 'wpNamespacesReason', 60, $defaultreason, array( 'tabindex' => '1', 'id' => 'mw-namespaces-editreason', 'maxlength' => '200' ) ) .
Html::hidden( 'wpNamespacesAction', $action ) .
$old .
Html::hidden( 'wpEditToken', $token ) .
' |
' .
'' . Xml::submitButton( $button, array( 'id' => 'mw-namespaces-submit' ) ) . ' |
' .
Xml::closeElement( 'table' ) .
Xml::closeElement( 'form' ) .
Xml::closeElement( 'fieldset' )
);
break;
}
}
function doSubmit() {
$req = $this->getRequest();
$nsoldname = $req->getVal( 'wpNamespacesOldName' );
$nsid = $req->getVal( 'wpNamespacesID' );
$do = $req->getVal( 'wpNamespacesAction' );
$nsoldname = str_replace( '+', '_', $nsoldname );
if ( preg_match( '/[\s:&=]/', $nsid ) ) {
$this->error( 'namespaces-badprefix', htmlspecialchars( $nsid ) );
$this->showForm( $do );
return;
}
$reason = $req->getText( 'wpNamespacesReason' );
$selfTitle = $this->getTitle();
$dbw = wfGetDB( DB_MASTER );
switch ( $do ) {
case "delete":
$dbw->delete( 'namespace_names', array( 'ns_name' => $nsoldname, 'ns_id' => $nsid ), __METHOD__ );
if ( $dbw->affectedRows() == 0 ) {
$this->error( 'namespaces_delfailed', $nsoldname );
$this->showForm( $do );
} else {
$this->getOutput()->addWikiText( wfMessage( 'namespaces_deleted', $nsoldname )->text() );
$this->getOutput()->returnToMain( false, $selfTitle );
$log = new LogPage( 'namespaces' );
$log->addEntry( 'ns_delete', $selfTitle, $reason, array( $nsoldname ) );
}
$this->discard();
break;
case "edit":
case "add":
$newname = $req->getVal( 'wpNamespacesName' );
$nsdefault = $req->getCheck( 'wpNamespacesDefault' ) ? 1 : 0;
$nscanonical = $req->getCheck( 'wpNamespacesCanonical' ) ? 1 : 0;
$data = array( 'ns_id' => $nsid, 'ns_name' => $newname,
'ns_default' => $nsdefault, 'ns_canonical' => $nscanonical );
if ( $do == 'add' ) {
$dbw->insert( 'namespace_names', $data, __METHOD__, 'IGNORE' );
} else {
$dbw->update( 'namespace_names', $data, array( 'ns_name' => $nsoldname ), __METHOD__, 'IGNORE' );
}
if ( $dbw->affectedRows() == 0 ) {
$this->error( "namespaces_{$do}failed", $nsid );
$this->showForm( $do );
} else {
$this->getOutput()->addWikiMsg( "namespaces_{$do}ed", $nsid );
$this->getOutput()->returnToMain( false, $selfTitle );
$log = new LogPage( 'namespaces' );
$log->addEntry( 'ns_' . $do, $selfTitle, $reason, array( $nsid, $newname, $nsdefault, $nscanonical ) );
}
$this->discard();
break;
}
}
function trans_default( $tl, $msg0, $msg1 ) {
if ( $tl === '0' )
return $msg0;
if ( $tl === '1' )
return $msg1;
return htmlspecialchars( $tl );
}
function showList( $admin ) {
global $wgScriptPath;
$this->getOutput()->addExtensionStyle( "{$wgScriptPath}/extensions/Namespaces/SpecialNamespaces.css" );
$nsidmessage = wfMessage( 'namespaces_nsid' )->parse();
$nsnamemessage = wfMessage( 'namespaces_nsname' )->parse();
$nsdefaultmessage = wfMessage( 'namespaces_default' )->parse();
$nscanonicalmessage = wfMessage( 'namespaces_canonical' )->parse();
$message_0 = wfMessage( 'namespaces_0' )->parse();
$message_1 = wfMessage( 'namespaces_1' )->parse();
$out = '
' . $nsidmessage . ' | ' . wfMessage( 'namespaces_nsid_intro' )->parse() . ' |
' . $nsnamemessage . ' | ' . wfMessage( 'namespaces_nsname_intro' )->parse() . ' |
' . $nsdefaultmessage . ' | ' . wfMessage( 'namespaces_default_intro' )->parse() . ' |
' . $message_1 . ' | ' . wfMessage( 'namespaces_default_1_intro' )->parse() . ' |
' . $message_0 . ' | ' . wfMessage( 'namespaces_default_0_intro' )->parse() . ' |
' . $nscanonicalmessage . ' | ' . wfMessage( 'namespaces_canonical_intro' )->parse() . ' |
';
$out .= '
' . $message_1 . ' | ' . wfMessage( 'namespaces_canonical_1_intro' )->parse() . ' |
' . $message_0 . ' | ' . wfMessage( 'namespaces_canonical_0_intro' )->parse() . ' |
';
$out .= '
';
$this->getOutput()->addWikiMsg( 'namespaces_intro' );
$this->getOutput()->addHTML( $out );
$this->getOutput()->addWikiMsg( 'namespaces_intro_footer' );
$selfTitle = $this->getTitle();
if ( $admin ) {
$skin = $this->getUser()->getSkin();
$addtext = wfMessage( 'namespaces_addtext' )->parse();
$addlink = Linker::link( $selfTitle, $addtext, array(), array( 'action' => 'add' ) );
$this->getOutput()->addHTML( '' . $addlink . '
' );
}
$dbr = wfGetDB( DB_SLAVE );
$res = $dbr->select( 'namespace_names', '*', 1, __METHOD__, array( 'ORDER BY' => 'ns_id' ) );
$numrows = $res->numRows();
if ( $numrows == 0 ) {
$this->error( 'namespaces_error' );
return;
}
$out = "
\n";
while ( $s = $res->fetchObject() ) {
$nsid = htmlspecialchars( $s->ns_id );
$nsname = htmlspecialchars( $s->ns_name );
$nsdefault = $this->trans_default( $s->ns_default, $message_0, $message_1 );
$nscanonical = $this->trans_default( $s->ns_canonical, $message_0, $message_1 );
$out .= "
$nsid |
$nsname |
$nsdefault |
$nscanonical | ";
if ( $admin ) {
$out .= '';
$out .= $skin->link( $selfTitle, $editmessage, array(),
array( 'action' => 'edit', 'prefix' => $nsid, 'name' => $nsname ) );
$out .= ', ';
$out .= $skin->link( $selfTitle, $deletemessage, array(),
array( 'action' => 'delete', 'prefix' => $nsid, 'name' => $nsname ) );
$out .= ' | ';
}
$out .= "\n
\n";
}
$res->free();
$out .= "
";
$this->getOutput()->addHTML( $out );
}
function error() {
$args = func_get_args();
$this->getOutput()->wrapWikiMsg( "$1
", $args );
}
}
SpecialNamespaces-1.0gerrit/namespace_names.pg.sql 0000644 0000000 0000000 00000000435 12136763515 0022425 0 ustar 00root root 0000000 0000000 -- This is the Postgres version
-- See namespace_names.sql for the original version
BEGIN;
CREATE TABLE namespace_names (
ns_id INTEGER NOT NULL DEFAULT 0,
ns_name TEXT NOT NULL DEFAULT '',
ns_default INTEGER NOT NULL DEFAULT 0,
ns_canonical INTEGER DEFAULT NULL
);
COMMIT;
SpecialNamespaces-1.0gerrit/namespace_names.sql 0000644 0000000 0000000 00000000632 12136763515 0022017 0 ustar 00root root 0000000 0000000 -- Tables for the SpecialNamespaces extension
-- vim: autoindent syn=mysql sts=2 sw=2
-- Replace /*$wgDBprefix*/ with the proper prefix
CREATE TABLE /*$wgDBprefix*/namespace_names (
`ns_id` INT(8) NOT NULL DEFAULT '0',
`ns_name` VARCHAR(200) NOT NULL DEFAULT '',
`ns_default` tinyint(1) NOT NULL DEFAULT '0',
`ns_canonical` tinyint(1) DEFAULT NULL,
PRIMARY KEY (`ns_name`)
) /*$wgDBTableOptions*/;