more or less work for now.
* user_groups ur_group is now a short string key ('sysop' etc)
* groups table is gone
* user_rights table is gone
* Permissions for groups are for now set in $wgGroupPermissions.
An in-database management system could be re-added in the future
if it's really needed, but for now it's mostly just been screwing
things up.
* Group.php and Special:Groups are deprecated; will probably die.
* User group memberships are set explicitly through addGroup and
removeGroup methods instead of being re-saved on every change to
the user record.
Group keys are migrated from user_rights at upgrade time for older wikis.
The fields in prior 1.5alpha tables were too screwed up and will need to
manually have sysops re-assigned.
The Makesysop extension will need some minor tweaks.
* (bug 2309) Allow templates and template parameters in HTML attribute zone,
with proper validation checks. (regression from fix for 2304)
* Disallow close tags and enforce empty tags for <hr> and <br>
+* Changed user_groups format quite a bit.
=== Caveats ===
print "<li>Creating tables...";
dbsource( "../maintenance/tables.sql", $wgDatabase );
dbsource( "../maintenance/interwiki.sql", $wgDatabase );
- dbsource( "../maintenance/archives/patch-userlevels-defaultgroups.sql", $wgDatabase );
print " done.</li>\n";
print "<li>Initializing data...";
if ( 0 == $u->idForName() ) {
$u->addToDatabase();
$u->setPassword( $conf->getSysopPass() );
- $u->addRight( "sysop" );
- $u->addRight( "bureaucrat" );
$u->saveSettings();
+
+ $u->addGroup( "sysop" );
+ $u->addGroup( "bureaucrat" );
print "<li>Created sysop account <tt>" .
htmlspecialchars( $conf->SysopName ) . "</tt>.</li>\n";
$wgAutoblockExpiry = 86400; # Number of seconds before autoblock entries expire
/**
- * Static user groups serialized record
- * To avoid database access, you can set this to a user groups record as returned
- * by Special:Groups with the magic parameter showrecord=1. This will however mean
- * that you won't be able to edit them at runtime.
- */
-$wgStaticGroups = false;
+ * Permission keys given to users in each group.
+ * All users are implicitly in the '*' group including anonymous visitors;
+ * logged-in users are all implicitly in the 'user' group. These will be
+ * combined with the permissions of all groups that a given user is listed
+ * in in the user_groups table.
+ */
+$wgGroupPermissions = array(
+ '*' => array( 'read', 'createaccount' ),
+ 'user' => array( 'read', 'move' ),
+
+ 'bot' => array( 'bot' ),
+ 'sysop' => array( 'createaccount', 'patrol', 'protect', 'delete',
+ 'rollback', 'block', 'editinterface' ),
+ 'bureaucrat' => array( 'userrights' ),
+ 'steward' => array( 'makesysop' ), # technically this is for an extension...
+ 'developer' => array( 'siteadmin' ),
+);
+
+
# Proxy scanner settings
#
# $wgLocaltimezone = 'CET';
$wgLocaltimezone = null;
-/**
- * User level management
- * The number is the database id of a group you want users to be attached by
- * default. A better interface should be coded [av]
- */
-$wgAnonGroupId = 1;
-$wgLoggedInGroupId = 2;
-
/**
* When translating messages with wfMsg(), it is not always clear what should be
* @param boolean $reverse If true, multiple select will hide selected elements (default false).
*/
function HTMLSelectGroups($selectname, $selectmsg, $selected=array(), $multiple=false, $size=6, $reverse=false) {
- global $wgOut;
- $groups =& Group::getAllGroups();
+ $groups = User::getAllGroups();
+ $out = htmlspecialchars( wfMsg( $selectmsg ) );
- $out = wfMsg($selectmsg);
- $out .= '<select name="'.$selectname;
- if($multiple) { $out.='[]" multiple="multiple" size="'.$size; }
- $out.= "\">\n";
+ if( $multiple ) {
+ $attribs = array(
+ 'name' => $selectname . '[]',
+ 'multiple'=> 'multiple',
+ 'size' => $size );
+ } else {
+ $attribs = array( 'name' => $selectname );
+ }
+ $out .= wfElement( 'select', $attribs, null );
- foreach ( $groups as $id => $g ) {
- if($multiple) {
+ foreach( $groups as $group ) {
+ $attribs = array( 'value' => $group );
+ if( $multiple ) {
// for multiple will only show the things we want
- if(in_array($id, $selected) xor $reverse) {
- $out .= '<option value="'.$id.'">'.$wgOut->parse( $g->getExpandedName() )."</option>\n";
+ if( !in_array( $group, $selected ) xor $reverse ) {
+ continue;
}
} else {
- $out .= '<option ';
- if(in_array($id, $selected)) { $out .= 'selected="selected" '; }
- $out .= 'value="'.$id.'">'.$wgOut->parse( $g->getExpandedName() )."</option>\n";
+ if( in_array( $group, $selected ) ) {
+ $attribs['selected'] = 'selected';
+ }
}
+ $out .= wfElement( 'option', $attribs, User::getGroupName( $group ) ) . "\n";
}
+
$out .= "</select>\n";
return $out;
}
// form header
$out = '<form method="get" action="'.$action.'">' .
'<input type="hidden" name="title" value="'.$special.'" />' .
- wfMsg( 'grouplevels-editgroup-name' ) . '<select name="group">';
+ wfMsg( 'groups-editgroup-name' ) . '<select name="group">';
// get all group names and IDs
- $groups =& Group::getAllGroups();
+ $groups = User::getAllGroups();
// we want a default empty group
$out.= '<option value=""></option>';
// build the dropdown list menu using datas from the database
foreach ( $groups as $group ) {
- $selected = ($group->getId() == $this->requestedGroup) ? ' selected ' : '' ;
- $out.= '<option value="'.$group->getId().'" '.$selected.'>'.$group->getExpandedName().'</option>';
+ $selected = ($group == $this->requestedGroup);
+ $out .= wfElement( 'option',
+ array_merge(
+ array( 'value' => $group ),
+ $selected ? array( 'selected' => 'selected' ) : array() ),
+ User::getGroupName( $group ) );
}
$out .= '</select> ';
function getSQL() {
$dbr =& wfGetDB( DB_SLAVE );
- /* system showing possible actions for users
- $user = $dbr->tableName( 'user' );
- $user_rights = $dbr->tableName( 'user_rights' );
- $userspace = Namespace::getUser();
- return "SELECT ur_rights as type, $userspace as namespace, user_name as title, " .
- "user_name as value FROM $user LEFT JOIN $user_rights ON user_id = ur_user";
- */
- /** Show groups instead */
$user = $dbr->tableName( 'user' );
$user_groups = $dbr->tableName( 'user_groups' );
$userspace = NS_USER;
- $sql = "SELECT CONCAT('Listusers ', ug_group) as type, $userspace AS namespace, user_name AS title, user_name as value " .
+ $sql = "SELECT 'Listusers' as type, $userspace AS namespace, user_name AS title, ug_group as value " .
"FROM $user ".
"LEFT JOIN $user_groups ON user_id =ug_user ";
if($this->requestedGroup != '') {
- $sql .= "WHERE ug_group = '" . IntVal( $this->requestedGroup ) . "' ";
+ $sql .= 'WHERE ug_group = ' . $dbr->addQuotes( $this->requestedGroup ) . ' ';
if($this->requestedUser != '') {
$sql .= "AND user_name = " . $dbr->addQuotes( $this->requestedUser ) . ' ';
}
function clearGroups() {
$this->concatGroups = '';
}
-/*
- var $previousResult = false;
- var $concatGroups = '';
-*/
+
function formatResult( $skin, $result ) {
global $wgContLang;
$name = false;
}
if( is_object( $result ) && $result->type != '') {
- $group = Group::newFromId( intval( strstr( $result->type, ' ' ) ) );
+ $group = $result->value;
if ( $group ) {
- $groupName = $group->getExpandedName();
+ $groupName = User::getGroupName( $group );
$this->appendGroups( $skin->makeLink( wfMsgForContent( 'administrators' ), $groupName ) );
}
}
'Lockdb' => new SpecialPage( 'Lockdb', 'siteadmin' ),
'Unlockdb' => new SpecialPage( 'Unlockdb', 'siteadmin' ),
'Userrights' => new SpecialPage( 'Userrights', 'userrights' ),
- 'Groups' => new SpecialPage( 'Groups' ),
+ // 'Groups' => new SpecialPage( 'Groups' ), # currently borken
);
global $wgUseValidation ;
$fname = 'wfSpecialStatistics';
$dbr =& wfGetDB( DB_SLAVE );
- extract( $dbr->tableNames( 'page', 'site_stats', 'user', 'user_rights' ) );
+ extract( $dbr->tableNames( 'page', 'site_stats', 'user', 'user_groups' ) );
$sql = "SELECT COUNT(page_namespace) AS total FROM $page";
$res = $dbr->query( $sql, $fname );
$row = $dbr->fetchObject( $res );
$total = $row->total;
- $sql = "SELECT COUNT(ur_user) AS total FROM $user_rights WHERE ur_rights LIKE '%sysop%'";
+ $sql = "SELECT COUNT(*) AS total FROM $user_groups WHERE ug_group='sysop'";
$res = $dbr->query( $sql, $fname );
$row = $dbr->fetchObject( $res );
$admins = $row->total;
/** */
require_once('HTMLForm.php');
-require_once('Group.php');
/** Entry point */
function wfSpecialUserrights() {
$u = User::newFromName($username);
if(is_null($u)) {
- $wgOut->addHTML('<p>'.wfMsg('nosuchusershort',$username).'</p>');
+ $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $username ) ) );
return;
}
if($u->getID() == 0) {
- $wgOut->addHTML('<p>'.wfMsg('nosuchusershort',$username).'</p>');
+ $wgOut->addWikiText( wfMsg( 'nosuchusershort', htmlspecialchars( $username ) ) );
return;
}
$newGroups = array_merge($newGroups, $addgroup);
}
$newGroups = array_unique( $newGroups );
+
+ wfDebug( 'oldGroups: ' . print_r( $oldGroups, true ) );
+ wfDebug( 'newGroups: ' . print_r( $newGroups, true ) );
// save groups in user object and database
- $u->setGroups($newGroups);
- $u->saveSettings();
+ foreach( $removegroup as $group ) {
+ $u->removeGroup( $group );
+ }
+ foreach( $addgroup as $group ) {
+ $u->addGroup( $group );
+ }
$log = new LogPage( 'rights' );
$log->addEntry( 'rights', Title::makeTitle( NS_USER, $u->getName() ), '', array( $this->makeGroupNameList( $oldGroups ),
}
function makeGroupNameList( $ids ) {
- $s = '';
- foreach( $ids as $id ) {
- if ( $s != '' ) {
- $s .= ', ';
- }
- $groupObj = Group::newFromId( $id );
- $s .= $groupObj->getExpandedName();
- }
- return $s;
+ return implode( ', ', $ids );
}
/**
$wgOut->addHTML( "<form name=\"uluser\" action=\"$this->action\" method=\"post\">\n" );
$wgOut->addHTML( $this->fieldset( 'lookup-user',
$this->textbox( 'user-editname' ) .
- '<input type="submit" name="ssearchuser" value="'.wfMsg('editusergroup').'" />'
+ wfElement( 'input', array(
+ 'type' => 'submit',
+ 'name' => 'ssearchuser',
+ 'value' => wfMsg( 'editusergroup' ) ) )
));
$wgOut->addHTML( "</form>\n" );
}
global $wgOut;
$user = User::newFromName($username);
- $encUser = htmlspecialchars( $username );
- if(is_null($user)) {
- $wgOut->addHTML('<p>'.wfMsg('nosuchusershort', $encUser).'</p>');
+ if( is_null( $user ) || $user->getID() == 0 ) {
+ $wgOut->addWikiText( wfMsg( 'nosuchusershort', wfEscapeWikiText( $username ) ) );
return;
}
-
- if($user->getID() == 0) {
- $wgOut->addHTML('<p>'.wfMsg('nosuchusershort', $encUser).'</p>');
- return;
- }
$groups = $user->getGroups();
$wgOut->addHTML( "<form name=\"editGroup\" action=\"$this->action\" method=\"post\">\n".
- '<input type="hidden" name="user-editname" value="'.$encUser.'" />');
- $wgOut->addHTML( $this->fieldset( 'editusergroup',
- wfMsg('editing', $this->mRequest->getVal('user-editname')).".<br />\n" .
+ wfElement( 'input', array(
+ 'type' => 'hidden',
+ 'name' => 'user-editname',
+ 'value' => $username ) ) .
+ $this->fieldset( 'editusergroup',
+ $wgOut->parse( wfMsg('editing', $username ) ) .
'<table border="0" align="center"><tr><td>'.
HTMLSelectGroups('member', $this->mName.'-groupsmember', $groups,true,6).
'</td><td>'.
HTMLSelectGroups('available', $this->mName.'-groupsavailable', $groups,true,6,true).
'</td></tr></table>'."\n".
- '<p>'.wfMsg('userrights-groupshelp').'</p>'."\n".
- '<input type="submit" name="saveusergroups" value="'.wfMsg('saveusergroups').'" />'
+ $wgOut->parse( wfMsg('userrights-groupshelp') ) .
+ wfElement( 'input', array(
+ 'type' => 'submit',
+ 'name' => 'saveusergroups',
+ 'value' => wfMsg( 'saveusergroups' ) ) )
));
$wgOut->addHTML( "</form>\n" );
}
/** If anon users can create an account,
they need to reach the login page first! */
if( $wgUser->isAllowed( 'createaccount' )
- && $this->mId == NS_SPECIAL
+ && $this->getNamespace() == NS_SPECIAL
&& $this->getText() == 'Userlogin' ) {
return true;
}
*
*/
require_once( 'WatchedItem.php' );
-require_once( 'Group.php' );
# Number of characters in user_token field
define( 'USER_TOKEN_LENGTH', 32 );
var $mToken;
var $mRealName;
var $mHash;
- /** Array of group id the user belong to */
var $mGroups;
- /**#@-*/
/** Construct using User:loadDefaults() */
function User() {
* Load a user from the database
*/
function loadFromDatabase() {
- global $wgCommandLineMode, $wgAnonGroupId, $wgLoggedInGroupId;
+ global $wgCommandLineMode;
$fname = "User::loadFromDatabase";
# Counter-intuitive, breaks various things, use User::setLoaded() if you want to suppress
$this->mId = IntVal( $this->mId );
/** Anonymous user */
- if(!$this->mId) {
+ if( !$this->mId ) {
/** Get rights */
- $anong = Group::newFromId($wgAnonGroupId);
- if (!$anong)
- wfDebugDieBacktrace("Please update your database schema "
- ."and populate initial group data from "
- ."maintenance/archives patches");
- $anong->loadFromDatabase();
- $this->mRights = explode(',', $anong->getRights());
+ $this->mRights = $this->getGroupPermissions( array( '*' ) );
$this->mDataLoaded = true;
return;
} # the following stuff is for non-anonymous users only
$this->mTouched = wfTimestamp(TS_MW,$s->user_touched);
$this->mToken = $s->user_token;
- // Get groups id
- $res = $dbr->select( 'user_groups', array( 'ug_group' ), array( 'ug_user' => $this->mId ) );
-
- // add the default group for logged in user
- $this->mGroups = array( $wgLoggedInGroupId );
-
- while($group = $dbr->fetchRow($res)) {
- if ( $group[0] != $wgLoggedInGroupId ) {
- $this->mGroups[] = $group[0];
- }
- }
-
-
- $this->mRights = array();
- // now we merge groups rights to get this user rights
- foreach($this->mGroups as $aGroupId) {
- $g = Group::newFromId($aGroupId);
- $g->loadFromDatabase();
- $this->mRights = array_merge($this->mRights, explode(',', $g->getRights()));
+ $res = $dbr->select( 'user_groups',
+ array( 'ug_group' ),
+ array( 'ug_user' => $this->mId ),
+ $fname );
+ $this->mGroups = array();
+ while( $row = $dbr->fetchObject( $res ) ) {
+ $this->mGroups[] = $row->ug_group;
}
-
- // array merge duplicate rights which are part of several groups
- $this->mRights = array_unique($this->mRights);
-
- $dbr->freeResult($res);
+ $effectiveGroups = array_merge( array( '*', 'user' ), $this->mGroups );
+ $this->mRights = $this->getGroupPermissions( $effectiveGroups );
}
$this->mDataLoaded = true;
$this->loadFromDatabase();
return $this->mRights;
}
-
- function addRight( $rname ) {
- $this->loadFromDatabase();
- array_push( $this->mRights, $rname );
- $this->invalidateCache();
- }
+ /**
+ * Get the list of explicit group memberships this user has.
+ * The implicit * and user groups are not included.
+ * @return array of strings
+ */
function getGroups() {
$this->loadFromDatabase();
return $this->mGroups;
}
- function setGroups($groups) {
- $this->loadFromDatabase();
- $this->mGroups = $groups;
+ /**
+ * Get the list of implicit group memberships this user has.
+ * This includes all explicit groups, plus 'user' if logged in
+ * and '*' for all accounts.
+ * @return array of strings
+ */
+ function getEffectiveGroups() {
+ $base = array( '*' );
+ if( $this->isLoggedIn() ) {
+ $base[] = 'user';
+ }
+ return array_merge( $base, $this->getGroups() );
+ }
+
+ /**
+ * Remove the user from the given group.
+ * This takes immediate effect.
+ * @string $group
+ */
+ function addGroup( $group ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->insert( 'user_groups',
+ array(
+ 'ug_user' => $this->getID(),
+ 'ug_group' => $group,
+ ),
+ 'User::addGroup',
+ array( 'IGNORE' ) );
+
+ $this->mGroups = array_merge( $this->mGroups, array( $group ) );
+ $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups() );
+
$this->invalidateCache();
+ $this->saveSettings();
+ }
+
+ /**
+ * Remove the user from the given group.
+ * This takes immediate effect.
+ * @string $group
+ */
+ function removeGroup( $group ) {
+ $dbw =& wfGetDB( DB_MASTER );
+ $dbw->delete( 'user_groups',
+ array(
+ 'ug_user' => $this->getID(),
+ 'ug_group' => $group,
+ ),
+ 'User::removeGroup' );
+
+ $this->mGroups = array_diff( $this->mGroups, array( $group ) );
+ $this->mRights = User::getGroupPermissions( $this->getEffectiveGroups() );
+
+ $this->invalidateCache();
+ $this->saveSettings();
}
+
/**
* A more legible check for non-anonymousness.
* Returns true if the user is not an anonymous visitor.
'user_id' => $this->mId
), $fname
);
- $dbw->set( 'user_rights', 'ur_rights', implode( ',', $this->mRights ),
- 'ur_user='. $this->mId, $fname );
$wgMemc->delete( "$wgDBname:user:id:$this->mId" );
-
- // delete old groups
- $dbw->delete( 'user_groups', array( 'ug_user' => $this->mId), $fname);
-
- // save new ones
- foreach ($this->mGroups as $group) {
- $dbw->replace( 'user_groups',
- array(array('ug_user','ug_group')),
- array(
- 'ug_user' => $this->mId,
- 'ug_group' => $group
- ), $fname
- );
- }
}
), $fname
);
$this->mId = $dbw->insertId();
- $dbw->insert( 'user_rights',
- array(
- 'ur_user' => $this->mId,
- 'ur_rights' => implode( ',', $this->mRights )
- ), $fname
- );
-
- foreach ($this->mGroups as $group) {
- $dbw->insert( 'user_groups',
- array(
- 'ug_user' => $this->mId,
- 'ug_group' => $group
- ), $fname
- );
- }
}
function spreadBlock() {
return false;
return true;
}
+
+ /**
+ * @param array $groups list of groups
+ * @return array list of permission key names for given groups combined
+ * @static
+ */
+ function getGroupPermissions( $groups ) {
+ global $wgGroupPermissions;
+ $rights = array();
+ foreach( $groups as $group ) {
+ if( isset( $wgGroupPermissions[$group] ) ) {
+ $rights = array_merge( $rights, $wgGroupPermissions[$group] );
+ }
+ }
+ return $rights;
+ }
+
+ /**
+ * @param string $group key name
+ * @return string localized descriptive name, if provided
+ * @static
+ */
+ function getGroupName( $group ) {
+ $key = "group-$group-name";
+ $name = wfMsg( $key );
+ if( $name == '' || $name == "<$key>" ) {
+ return $group;
+ } else {
+ return $name;
+ }
+ }
+
+ /**
+ * Return the set of defined explicit groups.
+ * The * and 'user' groups are not included.
+ * @return array
+ * @static
+ */
+ function getAllGroups() {
+ global $wgGroupPermissions;
+ return array_diff(
+ array_keys( $wgGroupPermissions ),
+ array( '*', 'user' ) );
+ }
+
}
?>
--- /dev/null
+--
+-- User permissions have been broken out to a separate table;
+-- this allows sites with a shared user table to have different
+-- permissions assigned to a user in each project.
+--
+-- This table replaces the old user_rights field which used a
+-- comma-separated blob.
+--
+CREATE TABLE /*$wgDBprefix*/user_groups (
+ -- Key to user_id
+ ug_user int(5) unsigned NOT NULL default '0',
+
+ -- Group names are short symbolic string keys.
+ -- The set of group names is open-ended, though in practice
+ -- only some predefined ones are likely to be used.
+ --
+ -- At runtime $wgGroupPermissions will associate group keys
+ -- with particular permissions. A user will have the combined
+ -- permissions of any group they're explicitly in, plus
+ -- the implicit '*' and 'user' groups.
+ ug_group char(16) NOT NULL default '',
+
+ PRIMARY KEY (ug_user,ug_group),
+ KEY (ug_group)
+) TYPE=InnoDB;
'recentchanges',
'watchlist', 'math', 'searchindex',
'interwiki', 'querycache',
- 'objectcache', 'groups'
+ 'objectcache'
);
}
'iw_local' => 1 ),
) );
- # Hack: initialize a group
- $db->insert( 'groups', array(
- 'gr_id' => 1,
- 'gr_name' => 'Anonymous',
- 'gr_description' => 'Anonymous users',
- 'gr_rights' => 'read' ) );
-
# Hack: Insert an image to work with
$db->insert( 'image', array(
'img_name' => 'Foobar.jpg',
-- this allows sites with a shared user table to have different
-- permissions assigned to a user in each project.
--
--- TODO: de-blob this; it should be a property table
+-- This table replaces the old user_rights field which used a
+-- comma-separated blob.
--
-CREATE TABLE /*$wgDBprefix*/user_rights (
+CREATE TABLE /*$wgDBprefix*/user_groups (
-- Key to user_id
- ur_user int(5) unsigned NOT NULL,
-
- -- Comma-separated list of permission keys
- ur_rights tinyblob NOT NULL default '',
+ ug_user int(5) unsigned NOT NULL default '0',
- UNIQUE KEY ur_user (ur_user)
-
+ -- Group names are short symbolic string keys.
+ -- The set of group names is open-ended, though in practice
+ -- only some predefined ones are likely to be used.
+ --
+ -- At runtime $wgGroupPermissions will associate group keys
+ -- with particular permissions. A user will have the combined
+ -- permissions of any group they're explicitly in, plus
+ -- the implicit '*' and 'user' groups.
+ ug_group char(16) NOT NULL default '',
+
+ PRIMARY KEY (ug_user,ug_group),
+ KEY (ug_group)
) TYPE=InnoDB;
-- The following table is no longer needed with Enotif >= 2.00
-- Hold group name and description
-CREATE TABLE /*$wgDBprefix*/groups (
- gr_id int(5) unsigned NOT NULL auto_increment,
- gr_name varchar(50) NOT NULL default '',
- gr_description varchar(255) NOT NULL default '',
- gr_rights tinyblob,
- PRIMARY KEY (gr_id)
-
-) TYPE=InnoDB;
-
--- Relation table between user and groups
-CREATE TABLE /*$wgDBprefix*/user_groups (
- ug_user int(5) unsigned NOT NULL default '0',
- ug_group int(5) unsigned NOT NULL default '0',
- PRIMARY KEY (ug_user,ug_group)
-
-) TYPE=InnoDB;
+--CREATE TABLE /*$wgDBprefix*/groups (
+-- gr_id int(5) unsigned NOT NULL auto_increment,
+-- gr_name varchar(50) NOT NULL default '',
+-- gr_description varchar(255) NOT NULL default '',
+-- gr_rights tinyblob,
+-- PRIMARY KEY (gr_id)
+--
+--) TYPE=InnoDB;
$wgRenamedTables = array(
# from to patch file
- array( 'group', 'groups', 'patch-rename-group.sql' ),
+# array( 'group', 'groups', 'patch-rename-group.sql' ),
);
$wgNewTables = array(
array( 'objectcache', 'patch-objectcache.sql' ),
array( 'categorylinks', 'patch-categorylinks.sql' ),
array( 'logging', 'patch-logging.sql' ),
- array( 'user_rights', 'patch-user_rights.sql' ),
- array( 'groups', 'patch-userlevels.sql' ),
array( 'validate', 'patch-validate.sql' ),
);
array( 'user', 'user_real_name', 'patch-user-realname.sql' ),
array( 'user', 'user_token', 'patch-user_token.sql' ),
array( 'user', 'user_email_token', 'patch-user_email_token.sql' ),
- array( 'user_rights', 'ur_user', 'patch-rename-user_groups-and_rights.sql' ),
- array( 'groups', 'gr_rights', 'patch-userlevels-rights.sql' ),
array( 'logging', 'log_params', 'patch-log_params.sql' ),
array( 'archive', 'ar_rev_id', 'patch-archive-rev_id.sql' ),
array( 'archive', 'ar_text_id', 'patch-archive-text_id.sql' ),
}
}
-# Assumes that the groups table has been added.
-function do_group_update() {
- global $wgDatabase;
- $res = $wgDatabase->safeQuery( 'SELECT COUNT(*) AS c FROM !',
- $wgDatabase->tableName( 'groups' ) );
- $row = $wgDatabase->fetchObject( $res );
- $wgDatabase->freeResult( $res );
- if( $row->c == 0 ) {
- echo "Adding default group definitions... ";
- dbsource( "maintenance/archives/patch-userlevels-defaultgroups.sql", $wgDatabase );
- echo "ok\n";
- }
-}
-
/**
* 1.4 betas were missing the 'binary' marker from logging.log_title,
* which causes a collation mismatch error on joins in MySQL 4.1.
}
}
+function do_user_groups_update() {
+ $fname = 'do_user_groups_update';
+ global $wgDatabase;
+
+ if( $wgDatabase->tableExists( 'user_groups' ) ) {
+ echo "...user_groups table already exists.\n";
+ return do_user_groups_reformat();
+ }
+
+ echo "Adding user_groups table... ";
+ dbsource( 'maintenance/archives/patch-user_groups.sql', $wgDatabase );
+ echo "ok\n";
+
+ if( !$wgDatabase->tableExists( 'user_rights' ) ) {
+ if( $wgDatabase->fieldExists( 'user', 'user_rights' ) ) {
+ echo "Upgrading from a 1.3 or older database? Breaking out user_rights for conversion...";
+ dbsource( 'maintenance/archives/patch-user_rights.sql', $wgDatabase );
+ echo "ok\n";
+ } else {
+ echo "*** WARNING: couldn't locate user_rights table or field for upgrade.\n";
+ echo "*** You may need to manually configure some sysops by manipulating\n";
+ echo "*** the user_groups table.\n";
+ return;
+ }
+ }
+
+ echo "Converting user_rights table to user_groups... ";
+ $result = $wgDatabase->select( 'user_rights',
+ array( 'ur_user', 'ur_rights' ),
+ array( "ur_rights != ''" ),
+ $fname );
+
+ while( $row = $wgDatabase->fetchObject( $result ) ) {
+ $groups = array_unique(
+ array_map( 'trim',
+ explode( ',', $row->ur_rights ) ) );
+
+ foreach( $groups as $group ) {
+ $wgDatabase->insert( 'user_groups',
+ array(
+ 'ug_user' => $row->ur_user,
+ 'ug_group' => $group ),
+ $fname );
+ }
+ }
+ $wgDatabase->freeResult( $result );
+ echo "ok\n";
+}
+
+function do_user_groups_reformat() {
+ # Check for bogus formats from previous 1.5 alpha code.
+ global $wgDatabase;
+ $info = $wgDatabase->fieldInfo( 'user_groups', 'ug_group' );
+
+ if( $info->type == 'int' ) {
+ $oldug = $wgDatabase->tableName( 'user_groups' );
+ $newug = $wgDatabase->tableName( 'user_groups_bogus' );
+ echo "user_groups is in bogus intermediate format. Renaming to $newug... ";
+ $wgDatabase->query( "ALTER TABLE $oldug RENAME TO $newug" );
+ echo "ok\n";
+
+ echo "Re-adding fresh user_groups table... ";
+ dbsource( 'maintenance/archives/patch-user_groups.sql', $wgDatabase );
+ echo "ok\n";
+
+ echo "***\n";
+ echo "*** WARNING: You will need to manually fix up user permissions in the user_groups\n";
+ echo "*** table. Old 1.5 alpha versions did some pretty funky stuff...\n";
+ echo "***\n";
+ } else {
+ echo "...user_groups is in current format.\n";
+ }
+
+}
+
function do_all_updates() {
global $wgNewTables, $wgNewFields, $wgRenamedTables;
flush();
}
- # Add default group data
- do_group_update(); flush();
-
# Do schema updates which require special handling
do_interwiki_update(); flush();
do_index_update(); flush();
do_drop_img_type(); flush();
do_user_unique_update(); flush();
+ do_user_groups_update(); flush();
initialiseMessages(); flush();
}