User:Ryan Schmidt/Extensions/GiveSyshalfop

GiveSyshalfop allows bureaucrats to give syshalfop permissions to non-sysop users (basically, syshalfop is a watered-down sysop). This extension is useful if you need a slightly more powerful group than normal users to revert vandalism, etc., but you don't need them to have all the powers of a normal sysop. This extension is really useful only if you have Makesysop installed as well, otherwise bureaucrats can just use Special:Userrights to grant and revoke syshalfop status (provided you define the rights somewhere in LocalSettings.php).

Usage
Go to Special:Givesyshalfop and enter a username. If the user already has syshalfop status, you can enter a comment and revoke it. If the user doesn't and is eligible for syshalfop status (pretty much they aren't a sysop already and they're autoconfirmed), then you can enter a comment and grant it. All actions are logged in a separate Syshalfop rights log. To change the rights syshalfops have, comment/uncomment the rights in GiveSyshalfop.php.

Installation
Copy the following files to GiveSyshalfop.php, GiveSyshalfop.page.php, and GiveSyshalfop.i18n.php in a GiveSyshalfop folder in your extensions directory (aka /extensions/GiveSyshalfop/). Then, add the following line to the bottom of your LocalSettings.php require_once("$IP/extensions/GiveSyshalfop/GiveSyshalfop.php");

GiveSyshalfop.php
 'Give Syshalfop', 'author' => ' Ryan Schmidt ', 'url' => 'http://strategywiki.org/wiki/User:Ryan_Schmidt/Extensions', 'version' => '1.0', 'description' => 'Allows bureaucrats to give syshalfop permissions to a non-sysop user', ); $wgAutoloadClasses['GiveSyshalfop'] = dirname( __FILE__ ). '/GiveSyshalfop.page.php'; $wgSpecialPages['Givesyshalfop'] = 'GiveSyshalfop'; $wgAvailableRights[] = 'givesyshalfop';

$wgExtensionFunctions[] = 'efGiveSyshalfop';

/** $wgGroupPermissions['bureaucrat']['givesyshalfop'] = true;
 * Determines who can use the extension; as a default, bureaucrats are permitted

/** $wgGroupPermissions['syshalfop']['read']		= true; #can read pages $wgGroupPermissions['syshalfop']['edit']	 	= true; #can edit pages $wgGroupPermissions['syshalfop']['move']         	= true; #can move pages $wgGroupPermissions['syshalfop']['createpage'] 	= true; #can create pages $wgGroupPermissions['syshalfop']['createtalk'] 	= true; #can create talk pages $wgGroupPermissions['syshalfop']['upload']     	= true; #can upload $wgGroupPermissions['syshalfop']['reupload']           = true; #can upload over files $wgGroupPermissions['syshalfop']['reupload-shared']	= true; #can upload new files that replace a file on the shared image server $wgGroupPermissions['syshalfop']['minoredit'] 	 	= true; #can mark edits minor $wgGroupPermissions['syshalfop']['purge']	 	= true; #can use action=purge without a confirmation link $wgGroupPermissions['syshalfop']['createaccount'] 	= true; #can create new accounts $wgGroupPermissions['syshalfop']['patrol'] 		= true; #can patrol edits (leave enabled even if patrolling isn't, less stuff to modify if the time comes) $wgGroupPermissions['syshalfop']['autopatrol'] 		= true; #have their edits patrolled automatically (leave enabled even if patrolling isn't, less stuff to modify if the time comes) $wgGroupPermissions['syshalfop']['rollback'] 		= true; #allow them to rollback pages $wgGroupPermissions['syshalfop']['unwatchedpages'] 	= true; #allow them to view Special:Unwatchedpages $wgGroupPermissions['syshalfop']['autoconfirmed'] 	= true; #marks them autoconfirmed $wgGroupPermissions['syshalfop']['upload_by_url'] 	= true; #allows them to upload files by URL (only if $wgAllowCopyUploads = true) //$wgGroupPermissions['syshalfop']['import']		= true; #allows them to interwiki import and access Special:Import. $wgImportSources needs to be defined if the next permission isn't enabled //$wgGroupPermissions['syshalfop']['importupload']	= true; #allows them to import by file upload. If you disable this, but leave 'import' enabled, uncomment the next line //$wgImportSources = array('wikipedia', 'wikibooks'); 	#if 'import' is true but 'importupload' isn't, uncomment this. This specifies a list of interwiki prefixes where they can import pages from. $wgGroupPermissions['syshalfop']['protect']		= true; #allows them to protect/unprotect pages and edit protected pages //$wgGroupPermissions['syshalfop']['delete']		= true; #allows them to delete/undelete pages. If you uncomment this, uncomment the next line as well //$wgGroupPermissions['syshalfop']['deletedhistory']	= true; #allows them to view deleted history and use Special:DeletedContributions, if installed //$wgGroupPermissions['syshalfop']['block']		= true; #allows them to block and unblock users //$wgGroupPermissions['syshalfop']['ipblock-exempt']	= true; #they can still edit, etc. even if a block is active on the IP they're editing from (enable if 'block' is enabled) //$wgGroupPermissions['syshalfop']['editinterface']	= true; #allows them to edit MediaWiki messages and other user's personal CSS/JS pages (don't know why they're clumped together, but they are) //$wgGroupPermissions['syshalfop']['proxyunbannable']	= true; #not sure what this is, but I don't think it has much use. Putting it here because normal sysops have it
 * User group with extra capabilities (basically a watered down sysop)
 * Comment/Uncomment the permissions as needed by the wiki. Each permission is explained

/** function efGiveSyshalfop { global $wgMessageCache; require_once( dirname( __FILE__ ) . '/GiveSyshalfop.i18n.php' ); foreach( efGiveSyshalfopMessages as $lang => $messages ) $wgMessageCache->addMessages( $messages, $lang ); global $wgLogTypes, $wgLogNames, $wgLogHeaders, $wgLogActions; $wgLogTypes[] = 'gvsyshalfop'; $wgLogNames['gvsyshalfop'] = 'givesyshalfop-logpage'; $wgLogHeaders['gvsyshalfop'] = 'givesyshalfop-logpagetext'; $wgLogActions['gvsyshalfop/grant'] = 'givesyshalfop-logentrygrant'; $wgLogActions['gvsyshalfop/revoke'] = 'givesyshalfop-logentryrevoke'; }
 * Populate the message cache, set up the auditing and register the special page

} else { echo( "This file is an extension to the MediaWiki software and cannot be used standalone.\n" ); die( 1 ); }

GiveSyshalfop.page.php
<?php

/**
 * Class definition for the GiveSyshalfop special page
 * See http://strategywiki.org/wiki/User:Ryan_Schmidt/Extensions/GiveSyshalfop for more info.

define( 'MW_SYSHALFOP_GRANT', 1 ); define( 'MW_SYSHALFOP_REVOKE', 2 );

class GiveSyshalfop extends SpecialPage {

var $target = '';

/**	* Constructor */	function GiveSyshalfop { SpecialPage::SpecialPage( 'Givesyshalfop', 'givesyshalfop' ); }

/**	* Main execution function */	function execute( $par ) { global $wgRequest, $wgOut, $wgUser;

if( !$wgUser->isAllowed( 'givesyshalfop' ) ) { $wgOut->permissionRequired( 'givesyshalfop' ); return; }

$this->setHeaders;

$this->target = $par ? $par : $wgRequest->getText( 'username', '' );

$wgOut->addWikiText( wfMsg( 'givesyshalfop-header' ) ); $wgOut->addHtml( $this->makeSearchForm );

if( $this->target != '' ) { $wgOut->addHtml( wfElement( 'p', NULL, NULL ) ); $user = User::newFromName( $this->target ); if( is_object( $user ) && !is_null( $user ) ) { $user->load; # Valid username, check existence if( $user->getID ) { # Exists; check current privileges if( $user->isAllowed( 'autoconfirmed' ) ) { if( !in_array( 'sysop', $user->mGroups ) ) { if( $wgRequest->getCheck( 'dosearch' ) || !$wgRequest->wasPosted || !$wgUser->matchEditToken( $wgRequest->getVal( 'token' ), 'givesyshalfop' ) ) { # Exists, check group memberships if( in_array( 'syshalfop', $user->mGroups ) ) { # Member of the syshalfop group $wgOut->addWikiText( wfMsg( 'givesyshalfop-hashop', $user->getName ) ); $wgOut->addHtml( $this->makeGrantForm( MW_GIVESYSHALFOP_REVOKE ) ); } else { # Not a member; show the grant form $wgOut->addWikiText( wfMsg( 'givesyshalfop-nohop', $user->getName ) ); $wgOut->addHtml( $this->makeGrantForm( MW_GIVESYSHALFOP_GRANT ) ); }							} elseif( $wgRequest->getCheck( 'grant' ) ) { # Grant syshalfop rights $user->addGroup( 'syshalfop' ); $this->addLogItem( 'grant', $user, trim( $wgRequest->getText( 'comment' ) ) ); $wgOut->addWikiText( wfMsg( 'givesyshalfop-granted', $user->getName ) ); } elseif( $wgRequest->getCheck( 'revoke' ) ) { # Revoke syshalfop rights $user->removeGroup( 'syshalfop' ); $this->addLogItem( 'revoke', $user, trim( $wgRequest->getText( 'comment' ) ) ); $wgOut->addWikiText( wfMsg( 'givesyshalfop-revoked', $user->getName ) ); }							# Show log entries $this->showLogEntries( $user ); } else { # Sysops already have syshalfop permissions $wgOut->addWikiText( wfMsg( 'givesyshalfop-sysop', $user->getName ) ); }					} else { # User account is too new $wgOut->addWikiText( wfMsg( 'givesyshalfop-toonew', $user->getName ) ); }				} else { # Doesn't exist $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $this->target ) ) ); }			} else { # Invalid username $wgOut->addWikiText( wfMsg( 'noname' ) ); }		}

}

/**	* Produce a form to allow for entering a username */	function makeSearchForm { $thisTitle = Title::makeTitle( NS_SPECIAL, $this->getName ); $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $thisTitle->getLocalUrl ) ); $form .= wfElement( 'label', array( 'for' => 'username' ), wfMsg( 'givesyshalfop-username' ) ). ' ';		$form .= wfElement( 'input', array( 'type' => 'text', 'name' => 'username', 'id' => 'username', 'value' => $this->target ) ). ' ';		$form .= wfElement( 'input', array( 'type' => 'submit', 'name' => 'dosearch', 'value' => wfMsg( 'givesyshalfop-search' ) ) ); $form .= wfCloseElement( 'form' ); return $form; }

/**	* Produce a form to allow granting or revocation of the rights */	function makeGrantForm( $type ) { global $wgUser; $thisTitle = Title::makeTitle( NS_SPECIAL, $this->getName ); if( $type == MW_GIVESYSHALFOP_GRANT ) { $grant = true; $revoke = false; } else { $grant = false; $revoke = true; }

# Start the table $form = wfOpenElement( 'form', array( 'method' => 'post', 'action' => $thisTitle->getLocalUrl ) ); $form .= wfOpenElement( 'table' ). wfOpenElement( 'tr' ); # Grant/revoke buttons $form .= wfElement( 'td', array( 'align' => 'right' ), wfMsg( 'givesyshalfop-change' ) ); $form .= wfOpenElement( 'td' ); foreach( array( 'grant', 'revoke' ) as $button ) { $attribs = array( 'type' => 'submit', 'name' => $button, 'value' => wfMsg( 'givesyshalfop-'. $button ) ); if( !$$button ) $attribs['disabled'] = 'disabled'; $form .= wfElement( 'input', $attribs ); }		$form .= wfCloseElement( 'td' ). wfCloseElement( 'tr' ); # Comment field $form .= wfOpenElement( 'td', array( 'align' => 'right' ) ); $form .= wfElement( 'label', array( 'for' => 'comment' ), wfMsg( 'givesyshalfop-comment' ) ); $form .= wfOpenElement( 'td' ); $form .= wfElement( 'input', array( 'type' => 'text', 'name' => 'comment', 'id' => 'comment', 'size' => 45 ) ); $form .= wfCloseElement( 'td' ). wfCloseElement( 'tr' ); # End table $form .= wfCloseElement( 'table' ); # Username $form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'username', 'value' => $this->target ) ); # Edit token $form .= wfElement( 'input', array( 'type' => 'hidden', 'name' => 'token', 'value' => $wgUser->editToken( 'givesyshalfop' ) ) ); $form .= wfCloseElement( 'form' ); return $form; }

/**	* Add logging entries for the specified action */	function addLogItem( $type, &$target, $comment = '' ) { $log = new LogPage( 'gvsyshalfop' ); $targetPage = $target->getUserPage; $log->addEntry( $type, $targetPage, $comment ); }

/**	* Show the bot status log entries for the specified user */	function showLogEntries( &$user ) { global $wgOut; $title = $user->getUserPage; $wgOut->addHtml( wfElement( 'h2', NULL, htmlspecialchars( LogPage::logName( 'gvsyshalfop' ) ) ) ); $logViewer = new LogViewer( new LogReader( new FauxRequest( array( 'page' => $title->getPrefixedText, 'type' => 'gvsyshalfop' ) ) ) ); $logViewer->showList( $wgOut ); }

}

GiveSyshalfop.i18n.php
 array( 'givesyshalfop' => 'Grant or revoke syshalfop rights', 'givesyshalfop-header' => "A local bureaucrat can use this page to grant or revoke syshalfop rights to another user account. This can be used to allow non-sysops to perform basic administrative functions. This should be done in accordance with applicable policies.", 'givesyshalfop-username' => 'Username:', 'givesyshalfop-search' => 'Go', 'givesyshalfop-hashop' => '$1 has syshalfop rights.', 'givesyshalfop-nohop' => '$1 does not have syshalfop rights.', 'givesyshalfop-toonew' => '$1 is too new, and cannot be given syshalfop rights.', 'givesyshalfop-sysop' => '$1 is a sysop, and already has syshalfop permissions.', 'givesyshalfop-change' => 'Change status:', 'givesyshalfop-grant' => 'Grant', 'givesyshalfop-revoke' => 'Revoke', 'givesyshalfop-comment' => 'Comment:', 'givesyshalfop-granted' => '$1 now has syshalfop rights.', 'givesyshalfop-revoked' => '$1 no longer has syshalfop rights.', 'givesyshalfop-logpage' => 'Syshalfop rights log', 'givesyshalfop-logpagetext' => 'This is a log of changes to non-sysops\' syshalfop rights.', 'givesyshalfop-logentrygrant' => 'granted syshalfop rights to $1', 'givesyshalfop-logentryrevoke' => 'removed syshalfop rights from $1', )

);

return $messages;

}