Extension:SpecialNamespaces/sourcecode (ver 0.1)

<?php
/*
 * This is an extension to edit the list of namespaces, and is based on the
 * Special:Interwiki code originally by Stephanie Amanda Stevens. This is
 * not an officially-supported version of this code.
 *
 * 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.
 *
 * @author Based on Special:Interwiki, by Stephanie Amanda Stevens <phroziac@gmail.com>
 * @copyright Copyright (C) 2005 Stephanie Amanda Stevens
 * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
 */

if (!defined('MEDIAWIKI')) die();
$wgExtensionFunctions[] = "Namespaces";

$wgExtensionCredits['specialpage'][] = array(
        'name' => 'Special:Namespaces',
        'description' => 'adds a special page to view and manipulate the namespaces table.',
        'url' => 'http://www.mediawiki.org/wiki/Extension:Simple_namespaces',
        'author' => 'Carl Austin Bennett'
);

function Namespaces() {
        global $IP, $wgMessageCache, $wgHooks;
        require_once( "$IP/includes/SpecialPage.php" );

        $wgMessageCache->addMessage('namespaces', 'View and manipulate namespaces data');
        $wgMessageCache->addMessage('ns_delquestion', 'Deleting "$1"');
        $wgMessageCache->addMessage('ns_deleted', '$1 was successfully removed from the namespaces table.');
        $wgMessageCache->addMessage('ns_id', 'ID');
        $wgMessageCache->addMessage('ns_id2', 'ID:');
        $wgMessageCache->addMessage('ns_name', 'Name');
        $wgMessageCache->addMessage('ns_default', 'Default');
        $wgMessageCache->addMessage('ns_canonical', 'Canonical');
        $wgMessageCache->addMessage('ns_delete', 'Delete');
        $wgMessageCache->addMessage('ns_yes', 'Yes');
        $wgMessageCache->addMessage('ns_delfailed', '$1 could not be removed from the namespaces table.');
        $wgMessageCache->addMessage('ns_added', '$1 was successfully added to the namespaces table.');
        $wgMessageCache->addMessage('ns_addfailed', '$1 could not be added to the namespaces table.');
        $wgMessageCache->addMessage('ns_log_added', 'Added "$1" ($2) (local: $3) (trans: $4) to the namespaces table: $5');
        $wgMessageCache->addMessage('ns_alreadyexists', '$1 already exists in the namespace table!');
        $wgMessageCache->addMessage('ns_log_deleted', 'Removed prefix "$1" from the namespace table: $2');
        $wgMessageCache->addMessage('ns_add', '*Add a namespace prefix');
        $wgMessageCache->addMessage('ns_show', '*View all namespace prefixes');
        $wgMessageCache->addMessage('ns_logpagename', 'Namespace table log');
        $wgMessageCache->addMessage('ns_logpagetext', 'This is a log of changes to the namespace table.');
        $wgMessageCache->addMessage('ns_logentry', '');
        $wgMessageCache->addMessage('ns_reasonfield', 'Reason');
        $wgMessageCache->addMessage('ns_addtext', 'Add a namespace prefix');
        $wgMessageCache->addMessage('ns_delbutton', 'Delete');
        $wgMessageCache->addMessage('ns_addbutton', 'Add');

        # Add a new log type
        $wgHooks['LogPageValidTypes'][] = 'wfNamespacesAddLogType';
        $wgHooks['LogPageLogName'][] = 'wfNamespacesAddLogName';
        $wgHooks['LogPageLogHeader'][] = 'wfNamespacesAddLogHeader';
        $wgHooks['LogPageActionText'][] = 'wfNamespacesAddActionText';
        $wgHooks['LanguageNamespaces'][] = 'wfNamespaces';


        class Namespaces extends SpecialPage {
                function Namespaces() {
                        SpecialPage::SpecialPage( 'Namespaces' );
                        $this->includable( true );
                }

                function discard()
                {
                        global $wgDBname, $wgMemc;
                        $wgMemc->delete ("$wgDBname:SpecialNamespaces:names");
                        $wgMemc->delete ("$wgDBname:SpecialNamespaces:alias");
                }

                function execute( $par = null ) {
                        $fname = 'Namespaces::execute';
                        global $wgOut, $wgRequest, $wgUser;

                        $this->setHeaders();
                        $wgOut->setPagetitle( wfMsg( 'namespaces' ) );
                        $do = $wgRequest->getVal( 'do' );

                        // Some common checks
                        $admin = $wgUser->isAllowed( 'delete' );
                        $selfTitle = Title::makeTitle( NS_SPECIAL, 'Namespaces' );

                        // Protect administrative actions against malicious requests
                        $safePost = $wgRequest->wasPosted() &&
                                $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) );

                        if ($do == "delete") {
                                if (!$admin) { $wgOut->permissionRequired('namespaces'); return; }

                                $prefix = $wgRequest->getVal( 'prefix' );
                                $encPrefix = htmlspecialchars( $prefix );

                                $action = $selfTitle->escapeLocalURL( "do=delete2" );
                                $button = wfMsgHtml("ns_delbutton");
                                $question = htmlspecialchars( wfMsg('ns_delquestion', $prefix) );
                                $reasonmessage = wfMsgHtml('ns_reasonfield');
                                $token = htmlspecialchars( $wgUser->editToken() );

                                $out = $question;
                                $out .= "<form id=\"delete\" method=\"post\" action=\"{$action}\">
                                        <input type=\"hidden\" name=\"prefix\" value=\"{$encPrefix}\" />
                                        $reasonmessage <input tabindex='1' type='text' name=\"reason\" maxlength='200' size='60' />
                                        <input type=\"submit\" name=\"delete\" value=\"{$button}\" />
                                        <input type=\"hidden\" name=\"wpEditToken\" value=\"{$token}\"/>
                                        </form>\n";
                        } elseif ($do == "delete2" && $safePost) {
                                if (!$admin) { $wgOut->permissionRequired('namespaces'); return; }
                                $prefix = $wgRequest->getVal('prefix');
                                $reason = $wgRequest->getText('reason');
                                $deletedmessage = htmlspecialchars( wfMsg('ns_deleted', $prefix) );
                                $delfailedmessage = htmlspecialchars( wfMsg('ns_delfailed', $prefix) );

                                $dbw =& wfGetDB( DB_MASTER );
                                $dbw->delete( 'namespace_names', array( 'ns_id' => $prefix ), $fname );

                                if ($dbw->affectedRows() == 0) {
                                        $out = $delfailedmessage;
                                } else {
                                        $out = $deletedmessage;
                                        $log = new LogPage( 'namespaces' );
                                        $log->addEntry( 'namespaces', $selfTitle, wfMsgForContent( 'ns_log_deleted', $prefix, $reason ) );
                                }
                                $this->discard();
                        } elseif ($do == "add") {
                                if (!$admin) { $wgOut->permissionRequired('namespaces'); return; };
                                $action = $selfTitle->escapeLocalURL( "do=add2");
                                $prefixmessage = wfMsgHtml('ns_id');
                                $transmessage = wfMsgHtml('ns_canonical');
                                $localmessage = wfMsgHtml('ns_default');
                                $reasonmessage = wfMsgHtml('ns_reasonfield');
                                $urlmessage = wfMsgHtml('ns_name');
                                $button = wfMsgHtml('ns_addbutton');
                                $token = htmlspecialchars( $wgUser->editToken() );

                                $out = "<form id=\"add\" method=\"post\" action=\"{$action}\">
                                        $prefixmessage <input tabindex='1' type='text' name=\"prefix\" maxlength='20' size='20' /><br />
                                        $localmessage <input type=\"checkbox\" id=\"local\" name=\"local\" /><br />
                                        $transmessage <input type=\"checkbox\" id=\"trans\" name=\"trans\" /><br />

                                        $urlmessage <input tabindex='1' type='text' name=\"theurl\" maxlength='200' size='60' /><br />

                                        $reasonmessage <input tabindex='1' type='text' name=\"reason\" maxlength='200' size='60' /><br />

                                        <input type=\"submit\" name=\"add\" value=\"{$button}\" />
                                        <input type=\"hidden\" name=\"wpEditToken\" value=\"{$token}\" />
                                        </form>\n";
                        } elseif ($do == "add2" && $safePost) {
                                if (!$admin) { $wgOut->permissionRequired('namespaces'); return; }
                                $prefix = $wgRequest->getVal('prefix');
                                $reason = $wgRequest->getText('reason');
                                $theurl = $wgRequest->getVal('theurl');
                                $local = $wgRequest->getCheck('local') ? 1 : 0;
                                $trans = $wgRequest->getCheck('trans') ? 1 : 0;

                                $addedmessage = htmlspecialchars( wfMsg('ns_added', $prefix) );
                                $addfailedmessage = htmlspecialchars( wfMsg('ns_addfailed', $prefix) );
                                $alreadyexists = htmlspecialchars( wfMsg('ns_alreadyexists', $prefix) );

                                $dbw =& wfGetDB( DB_MASTER );
                                $dbw->insert( 'namespace_names',
                                        array(
                                                'ns_id' => $prefix,
                                                'ns_name'    => $theurl,
                                                'ns_default'  => $local,
                                                'ns_canonical'  => $trans ),
                                        $fname,
                                        'IGNORE' );

                                if( $dbw->affectedRows() == 0 ) {
                                        $out = $alreadyexists;
                                } else {
                                        $out = $addedmessage;
                                        $log = new LogPage( 'namespaces' );
                                        $log->addEntry( 'namespaces', $selfTitle, wfMsgForContent( 'ns_log_added', $prefix, $theurl, $trans, $local, $reason ) );
                                }
                                $this->discard();
                        } else {
                                $dbr =& wfGetDB( DB_SLAVE );
                                $res = $dbr->select( 'namespace_names', '*' );

                                $prefixmessage = wfMsgHtml('ns_id');
                                $urlmessage = wfMsgHtml('ns_name');
                                $localmessage = wfMsgHtml('ns_default');
                                $transmessage = wfMsgHtml('ns_canonical');
                                $deletemessage = wfMsgHtml('ns_delete');
                                $addtext = wfMsgHtml('ns_addtext');

                                if ($admin) {
                                        $skin = $wgUser->getSkin();
                                        $out = $skin->makeLinkObj( $selfTitle, $addtext, 'do=add' );
                                } else {
                                        $out = '';
                                }
                                $out .= "
                                <br />
                                <table width=\"100%\" border=\"2\">
                                <tr><td>$prefixmessage</td> <td>$urlmessage</td> <td>$localmessage</td> <td>$transmessage</td>";
                                if( $admin ) {
                                        $out .= "<td>$deletemessage</td>";
                                }

                                $out .= "</tr>\n";

                                $numrows = $dbr->numRows( $res );
                                if ($numrows == 0) {
                                        $out .= "<tr><td>The namespaces table is empty.</td></tr>";
                                }
                                while( $s = $dbr->fetchObject( $res ) ) {
                                        $prefix = htmlspecialchars( $s->ns_id );
                                        $url = htmlspecialchars( $s->ns_name);
                                        $trans = htmlspecialchars( $s->ns_canonical );
                                        $local = htmlspecialchars( $s->ns_default );
                                        $out .= "<tr><td>$prefix</td> <td>$url</td> <td>$local</td> <td>$trans</td>";
                                        if( $admin ) {
                                                $skin = $wgUser->getSkin();
                                                $out .= '<td>';
                                                $out .= $skin->makeLinkObj( $selfTitle, $deletemessage,
                                                        'do=delete&prefix=' . urlencode( $s->ns_id ) );
                                                $out .= '</td>';
                                        }

                                        $out .= "</tr>\n";
                                }
                                $dbr->freeResult( $res );
                                $out .= "</table><br />";
                        }
                        $wgOut->addHTML($out);
                }
        }

        SpecialPage::addPage( new Namespaces );
}

function wfNamespaces(&$namespaceNames,&$namespaceAliases)
{
# Insert translated custom namespace name/aliases from namespace_names database
# destination format is:
#     $this->namespaceNames[100]="ns_100";
#     $this->namespaceAliases =  array("Centurion" => 100);
#
        global $wgDBname,$wgMemc;
        $key = "$wgDBname:SpecialNamespaces:names";
        $cached = $wgMemc->get ($key);

        if (!is_array($cached))
        {
                $dbr =& wfGetDB( DB_SLAVE );
                $res = $dbr->select( 'namespace_names', '*' );
                $numrows = $dbr->numRows( $res );
                if ($numrows > 0)
                   while( $s = $dbr->fetchObject( $res ) ) {
                        $nsindex = htmlspecialchars( $s->ns_id );
                        $nsname = htmlspecialchars( $s->ns_name);
                        $nscanonical = htmlspecialchars( $s->ns_canonical );
                        $nsdefault = htmlspecialchars( $s->ns_default );

                        if ($nsdefault>0) $namespaceNames[$nsindex] = $nsname;
                        $namespaceAliases = $namespaceAliases + array($nsname => $nsindex);
                      }
                $dbr->freeResult( $res );
                $wgMemc->set ($key, $namespaceNames);
                $key = "$wgDBname:SpecialNamespaces:alias";
                $wgMemc->set ($key, $namespaceAliases);
        } else {
                $namespaceNames = $cached;
                $key = "$wgDBname:SpecialNamespaces:alias";
                $namespaceAliases = $wgMemc->get ($key);
        }
# fix for newer MW versions, which check for that return value (like 1.11.0)
        return true;
# ##
}

function wfNamespacesAddLogType( &$types ) {
        if ( !in_array( 'namespaces', $types ) )
                $types[] = 'namespaces';
        return true;
}

function wfNamespacesAddLogName( &$names ) {
        $names['namespaces'] = 'ns_logpagename';
        return true;
}

function wfNamespacesAddLogHeader( &$headers ) {
        $headers['namespaces'] = 'ns_logpagetext';
        return true;
}

function wfNamespacesAddActionText( &$actions ) {
        $actions['namespaces/namespaces'] = 'ns_logentry';
        return true;
}