New userlevel feature. Sysop only, for testing. NO FORM IS VALIDATED : use at your...
authorAntoine Musso <hashar@users.mediawiki.org>
Fri, 1 Oct 2004 15:57:09 +0000 (15:57 +0000)
committerAntoine Musso <hashar@users.mediawiki.org>
Fri, 1 Oct 2004 15:57:09 +0000 (15:57 +0000)
includes/HTMLForm.php
includes/SpecialSitesettings.php
includes/SpecialUserlevels.php [new file with mode: 0644]
includes/User.php
languages/Language.php
maintenance/archives/patch-userlevels.sql [new file with mode: 0644]

index b5b7084..bae40cb 100644 (file)
@@ -26,7 +26,7 @@ class HTMLForm {
         * @param boolean $checked Set true to check the box (default False).
         */
        function checkbox( $varname, $checked=false ) {
-               $checked = isset( $GLOBALS[$varname] ) && $GLOBALS[$varname] ;
+               $checked = isset( $_POST[$varname] ) && $_POST[$varname] ;
                return "<div><input type='checkbox' value=\"1\" id=\"{$varname}\" name=\"wpOp{$varname}\"" .
                        ( $checked ? ' checked="checked"' : '' ) .
                        " /><label for=\"{$varname}\">". wfMsg( $this->mName.'-'.$varname ) .
@@ -40,9 +40,9 @@ class HTMLForm {
         * @param integer $size Optional size of the textbox (default 20)
         */
        function textbox( $varname, $value='', $size=20 ) {
-               $value = isset( $GLOBALS[$varname] ) ? $GLOBALS[$varname] : $value;
+               $value = isset( $_POST[$varname] ) ? $_POST[$varname] : $value;
                return "<div><label>". wfMsg( $this->mName.'-'.$varname ) .
-                       "<input type='text' name=\"wpOp{$varname}\" value=\"{$value}\" size=\"{$size}\" /></label></div>\n";
+                       "<input type='text' name=\"{$varname}\" value=\"{$value}\" size=\"{$size}\" /></label></div>\n";
        }
 
        /* 
@@ -52,7 +52,7 @@ class HTMLForm {
         */
        function radiobox( $varname, $fields ) {
                foreach ( $fields as $value => $checked ) {
-                       $s .= "<div><label><input type='radio' name=\"wpOp{$varname}\" value=\"{$value}\"" .
+                       $s .= "<div><label><input type='radio' name=\"{$varname}\" value=\"{$value}\"" .
                                ( $checked ? ' checked="checked"' : '' ) . " />" . wfMsg( $this->mName.'-'.$varname.'-'.$value ) .
                                "</label></div>\n";
                }
@@ -66,9 +66,9 @@ class HTMLForm {
         * @param integer $size Optional size of the textarea (default 20)
         */
        function textareabox ( $varname, $value='', $size=20 ) {
-               $value = isset( $GLOBALS[$varname] ) ? $GLOBALS[$varname] : $value;
+               $value = isset( $_POST[$varname] ) ? $_POST[$varname] : $value;
                return '<div><label>'.wfMsg( $this->mName.'-'.$varname ).
-                      "<textarea name=\"wpOp{$varname}\" rows=\"5\" cols=\"{$size}\">$value</textarea>\n";
+                      "<textarea name=\"{$varname}\" rows=\"5\" cols=\"{$size}\">$value</textarea>\n";
        }
 
        /* 
@@ -78,13 +78,13 @@ class HTMLForm {
         */
        function arraybox( $varname , $size=20 ) {
                $s = '';
-               if ( isset( $GLOBALS[$varname] ) && is_array( $GLOBALS[$varname] ) ) {
-                       foreach ( $GLOBALS[$varname] as $index=>$element ) {
+               if ( isset( $_POST[$varname] ) && is_array( $_POST[$varname] ) ) {
+                       foreach ( $_POST[$varname] as $index=>$element ) {
                                $s .= $element."\n";
                        }
                }
                return "<div><label>".wfMsg( $this->mName.'-'.$varname ).
-                       "<textarea name=\"wpOp{$varname}\" rows=\"5\" cols=\"{$size}\">{$s}</textarea>\n";
+                       "<textarea name=\"{$varname}\" rows=\"5\" cols=\"{$size}\">{$s}</textarea>\n";
        }
 }
 ?>
index 536e5a8..a47751a 100644 (file)
@@ -18,6 +18,7 @@ class SiteSettingsForm extends HTMLForm {
        function SiteSettingsForm ( &$request ) {
                $this->mPosted = $request->wasPosted();
                $this->mRequest = $request;
+               $this->mName = 'sitesettings';
        }
 
        function execute() {
diff --git a/includes/SpecialUserlevels.php b/includes/SpecialUserlevels.php
new file mode 100644 (file)
index 0000000..071acbc
--- /dev/null
@@ -0,0 +1,257 @@
+<?php
+/**
+ * Provide an administration interface
+ * DO NOT USE: INSECURE.
+ */
+
+/** */
+require_once('HTMLForm.php');
+require_once('Group.php');
+
+/** Entry point */
+function wfSpecialUserlevels($par=null) {
+       global $wgRequest;
+       // print_r($_POST);
+       $form = new UserlevelsForm($wgRequest);
+       $form->execute();
+}
+
+/**
+ * A class to manage user levels rights.
+ */
+class UserlevelsForm extends HTMLForm {
+       var $mPosted, $mRequest, $mSaveprefs;
+       /** Escaped local url name*/
+       var $action;
+
+       /** Constructor*/
+       function UserlevelsForm ( &$request ) {
+               $this->mPosted = $request->wasPosted();
+               $this->mRequest = $request;
+               $this->mName = 'userlevels';
+               
+               $titleObj = Title::makeTitle( NS_SPECIAL, 'Userlevels' );
+               $this->action = $titleObj->escapeLocalURL();
+       }
+
+       /**
+        * Manage forms to be shown according to posted datas.
+        * Depending on the submit button used : Call a form or a saving function.
+        */
+       function execute() {
+               // show the general form
+               $this->switchForm();
+               if ( $this->mPosted ) {
+                       // show some more forms
+                       if($this->mRequest->getCheck('seditgroup')) {
+                               $this->editGroupForm( $this->mRequest->getVal($this->mName.'-group-edit') ); }
+                       if($this->mRequest->getCheck('saddgroup')) {
+                               $this->editGroupForm( ); }
+                       if($this->mRequest->getCheck('ssearchuser')) {
+                               $this->editUserGroupsForm( $this->mRequest->getVal('user-editname')); }
+
+                       // save settings
+                       if($this->mRequest->getCheck('savegroup')) {
+                               $this->saveGroup($this->mRequest->getVal('editgroup-name'),
+                                                $this->mRequest->getVal('editgroup-oldname'),
+                                                $this->mRequest->getVal('editgroup-description'));
+                       
+                       } elseif($this->mRequest->getCheck('saveusergroups')) {
+                               $this->saveUserGroups($this->mRequest->getVal('user-editname'),
+                                                     $this->mRequest->getVal($this->mName.'-groupsmember'),
+                                                     $this->mRequest->getVal($this->mName.'-groupsavailable'));
+                       }
+               }
+       }
+
+// save things !!
+       /**
+        * Save a group
+        * @param string $newname Group name.
+        * @param string $oldname Old (current) group name.
+        * @param string $description Group description.
+        * @todo FIXME : doesnt validate anything.
+        */
+       function saveGroup($newname, $oldname, $description) {
+               $newame = trim($newname);
+       
+               if($oldname == '') {
+               // We create a new group
+                       $g = new group();
+                       $g->addToDatabase();
+               } else {
+                       $g = Group::newFromName($oldname);
+               }
+               
+               // save stuff
+               $g->setName($newname);
+               $g->setDescription($description);
+               $g->save();
+       }
+
+       /**
+        * Save user groups changes in the database.
+        * Datas comes from the editUserGroupsForm() form function
+        *
+        * @param string $username Username to apply changes to.
+        * @param array $removegroup id of groups to be removed.
+        * @param array $addgroup id of groups to be added.
+        */
+       function saveUserGroups($username,$removegroup,$addgroup) {
+               $u = User::NewFromName($username);
+               
+               print "ADD:\n";
+               print_r($addgroup);
+               print "DEL:\n";
+               print_r($removegroup);
+               
+               if(is_null($u)) {
+                       $wgOut->addHTML('<p>'.wfMsg('nosuchusershort',$username).'</p>');
+                       return;
+               }
+               $id = $u->idForName();
+               if($id == 0) {
+                       $wgOut->addHTML('<p>'.wfMsg('nosuchusershort',$username).'</p>');
+                       return;
+               }               
+               $u->setID( $id );
+
+               $groups = $u->getGroups();
+               // remove then add groups               
+               $groups = array_diff($groups, $removegroup);
+               $groups = array_merge($groups, $addgroup);
+               // save groups in user object and database
+               $u->setGroups($groups);
+               $u->saveSettings();
+       }
+
+       /**
+        * The entry form
+        * It allow a user to select or eventually add a group as well as looking up
+        * for a username.
+        */
+       function switchForm() {
+               global $wgOut;
+               
+               // group selection              
+               $wgOut->addHTML( "<form name=\"ulgroup\" action=\"$this->action\" method=\"post\">" );
+               $wgOut->addHTML( $this->fieldset( 'lookup-group',
+                               $this->HTMLSelectGroups('group-edit', array(0 => $this->mRequest->getVal($this->mName.'-group-edit')) ) .
+                               ' <input type="submit" name="seditgroup" value="'.wfMsg('editgroup').'">' .
+                               '<br /><input type="submit" name="saddgroup" value="'.wfMsg('addgroup').'">'
+                       ));
+               $wgOut->addHTML( "</form>" );
+               
+               // user selection
+               $wgOut->addHTML( "<form name=\"uluser\" action=\"$this->action\" method=\"post\">" );
+               $wgOut->addHTML( $this->fieldset( 'lookup-user',
+                               $this->textbox( 'user-editname' ) .
+                               '<input type="submit" name="ssearchuser" value="'.wfMsg('editusergroup').'">'
+               ));
+               $wgOut->addHTML( "</form>" );
+       }
+
+       /**
+        * Edit a group properties and rights.
+        * @param string $groupname Name of a group to be edited.
+        */
+       function editGroupForm($groupID = 0) {
+               global $wgOut;
+               
+               if($this->mRequest->getVal('seditgroup')) {
+               // fetch data if we edit a group
+                       $g = Group::newFromID($groupID);
+                       $gName = $g->getName();
+                       $gDescription = $g->getDescription();
+                       $fieldname = 'editgroup';
+               } else {
+               // default datas when we add a group
+                       $gName = '';
+                       $gDescription = '';
+                       $fieldname = 'addgroup';
+               }
+
+               $wgOut->addHTML( "<form name=\"editGroup\" action=\"$this->action\" method=\"post\">".
+                               '<input type="hidden" name="editgroup-oldname" value="'.$gName.'">');
+               $wgOut->addHTML( $this->fieldset( $fieldname,
+                       $this->textbox( 'editgroup-name', $gName ) .
+                       $this->textareabox( 'editgroup-description', $gDescription ) .
+                       '<input type="submit" name="savegroup" value="'.wfMsg('savegroup').'">'
+                       ));
+               $wgOut->addHTML( "</form>" );
+       }
+
+       /**
+        * Edit user groups membership
+        * @param string $username Name of the user.
+        */
+       function editUserGroupsForm($username) {
+               global $wgOut;
+               
+               $user = User::newFromName($username);
+               if(is_null($user)) {
+                       $wgOut->addHTML('<p>'.wfMsg('nosuchusershort',$username).'</p>');
+                       return;
+               }
+               $id = $user->idForName();
+               if($id == 0) {
+                       $wgOut->addHTML('<p>'.wfMsg('nosuchusershort',$username).'</p>');
+                       return;
+               }               
+               $user->setID( $id );
+               
+               $groups = $user->getGroups();
+
+               $wgOut->addHTML( "<form name=\"editGroup\" action=\"$this->action\" method=\"post\">".
+                                                '<input type="hidden" name="user-editname" value="'.$username.'">');
+               $wgOut->addHTML( $this->fieldset( 'editusergroup',
+                       wfMsg('editing', $this->mRequest->getVal('user-editname')).'.<br />' .
+                       '<table border="0"><tr><td>'.
+                       $this->HTMLSelectGroups('groupsmember', $groups,true,6).
+                       '</td><td>'.
+                       $this->HTMLSelectGroups('groupsavailable', $groups,true,6,true).
+                       '</td></tr></table>'.
+                       '<p>'.wfMsg('userlevels-groupshelp').'</p>'.
+                       '<input type="submit" name="saveusergroups" value="'.wfMsg('saveusergroups').'">'
+                       ));
+               $wgOut->addHTML( "</form>" );
+       }
+
+
+       /** Build a select with all existent groups
+        * @param string $selectname Name of this element. Name of form is automaticly prefixed.
+        * @param array $selected Array of element selected when posted. Multiples will only show them.
+        * @param boolean $multiple A multiple elements select.
+        * @param integer $size Number of element to be shown ignored for non multiple (default 6).
+        * @param boolean $reverse If true, multiple select will hide selected elements (default false).
+       */
+       function HTMLSelectGroups($selectname, $selected=array(), $multiple=false, $size=6, $reverse=false) {
+               $selectname = $this->mName.'-'.$selectname;
+               $dbr =& wfGetDB( DB_SLAVE );
+               $sql = 'SELECT group_id, group_name FROM `group`';
+               $res = $dbr->query($sql,'wfSpecialAdmin');
+               
+               $out = wfMsg($selectname);
+               $out .= '<select name="'.$selectname;
+               if($multiple) { $out.='[]" multiple size="'.$size; }
+               $out.='">';
+               
+               while($g = $dbr->fetchObject( $res ) ) {
+                       if($multiple) {
+                               // for multiple will only show the things we want
+                               if(in_array($g->group_id, $selected) xor $reverse) { 
+                                       $out .= '<option value="'.$g->group_id.'">'.$g->group_name.'</option>';
+                               }
+                       } else {
+                               $out .= '<option ';
+                               if(in_array($g->group_id, $selected)) { $out .= 'selected '; }
+                               $out .= 'value="'.$g->group_id.'">'.$g->group_name.'</option>';
+                       }
+               }
+                       
+               $out .= '</select>';
+               return $out;
+       }
+
+}
+?>
index c4aa335..dfe3c4f 100644 (file)
@@ -30,6 +30,8 @@ class User {
        var $mToken;
        var $mRealName;
        var $mHash;
+       /** Array of group id the user belong to */
+       var $mGroups;
        /**#@-*/
 
        /** Construct using User:loadDefaults() */
@@ -142,6 +144,8 @@ class User {
                $this->mRealName = $this->mEmail = '';
                $this->mPassword = $this->mNewpassword = '';
                $this->mRights = array();
+               $this->mGroups = array();
+               
                // Getting user defaults only if we have an available language
                if(isset($wgContLang)) { $this->loadDefaultFromLanguage(); }
                
@@ -372,10 +376,19 @@ class User {
                        $this->mNewpassword = $s->user_newpassword;
                        $this->decodeOptions( $s->user_options );
                        $this->mTouched = wfTimestamp(TS_MW,$s->user_touched);
+                       $this->mToken = $s->user_token;
+                       
                        $this->mRights = explode( ",", strtolower( 
                                $dbr->selectField( 'user_rights', 'user_rights', array( 'user_id' => $this->mId ) )
                        ) );
-                       $this->mToken = $s->user_token;
+                       
+                       // Get groups id
+                       $sql = 'SELECT group_id FROM user_groups WHERE user_id = \''.$this->mId.'\';';
+                       $res = $dbr->query($sql,DB_SLAVE,$fname);
+                       while($group = $dbr->fetchRow($res)) {
+                               $this->mGroups[] = $group[0];
+                               }
+                       $dbr->freeResult($res);
                }
 
                $this->mDataLoaded = true;
@@ -520,13 +533,24 @@ class User {
                $this->loadFromDatabase();
                return $this->mRights;
        }
-
+       
        function addRight( $rname )     {
                $this->loadFromDatabase();
                array_push( $this->mRights, $rname );
                $this->invalidateCache();
        }
 
+       function getGroups() {
+               $this->loadFromDatabase();
+               return $this->mGroups;
+       }
+
+       function setGroups($groups) {
+               $this->loadFromDatabase();
+               $this->mGroups = $groups;
+               $this->invalidateCache();
+       }
+
        function isSysop() {
                $this->loadFromDatabase();
                if ( 0 == $this->mId ) { return false; }
@@ -739,9 +763,22 @@ class User {
                                'user_id' => $this->mId
                        ), $fname
                );
-               $dbw->set( 'user_rights', 'user_rights', implode( ",", $this->mRights ),
+               $dbw->set( 'user_rights', 'user_rights', implode( ',', $this->mRights ),
                        'user_id='. $this->mId, $fname ); 
                $wgMemc->delete( "$wgDBname:user:id:$this->mId" );
+               
+               // delete old groups
+               $dbw->delete( 'user_groups', array( 'user_id' => $this->mId), $fname);
+               // save new ones
+               foreach ($this->mGroups as $group) {
+                       $dbw->replace( 'user_groups',
+                               array(array('user_id','group_id')),
+                               array(
+                                       'user_id' => $this->mId,
+                                       'group_id' => $group
+                               ), $fname
+                       );
+               }
        }
 
        /**
@@ -788,7 +825,15 @@ class User {
                                'user_rights' => implode( ',', $this->mRights )
                        ), $fname
                );
-                               
+               
+               foreach ($this->mGroups as $group) {
+                       $dbw->insert( 'user_groups',
+                               array(
+                                       'user_id' => $this->mId,
+                                       'group_id' => $group
+                               ), $fname
+                       );
+               }
        }
 
        function spreadBlock() {
index cf7cdab..a9fb977 100644 (file)
@@ -815,6 +815,33 @@ from server time (UTC).',
 'emailflag'            => 'Disable e-mail from other users',
 'defaultns'            => 'Search in these namespaces by default:',
 
+# User levels special page
+#
+
+# switching pan
+'userlevels-lookup-group' => 'Manage group rights',
+'userlevels-group-edit' => 'Existent groups: ',
+'editgroup' => 'Edit Group',
+'addgroup' => 'Add Group',
+
+'userlevels-lookup-user' => 'Manage user groups',
+'userlevels-user-editname' => 'Enter a username: ',
+'editusergroup' => 'Edit User Groups',
+
+# group editing
+'userlevels-editgroup' => 'Edit group',
+'userlevels-addgroup' => 'Add group',
+'userlevels-editgroup-name' => 'Group name: ',
+'userlevels-editgroup-description' => 'Group description (max 255 characters):<br />',
+'savegroup' => 'Save Group',
+
+# user groups editing
+'userlevels-editusergroup' => 'Edit user groups',
+'saveusergroups' => 'Save User Groups',
+'userlevels-groupsmember' => 'Member of:',
+'userlevels-groupsavailable' => 'Available groups:',
+'userlevels-groupshelp' => 'Select groups you want the user to be removed from or added to.
+Unselected groups will not be changed. You can unselect a group by using CTRL + Left Click',
 # Recent changes
 #
 'changes' => 'changes',
@@ -1020,6 +1047,7 @@ in active use.',
 'booksources'  => 'Book sources',
 'categoriespagetext' => 'The following categories exists in the wiki.',
 'data' => 'Data',
+'userlevels' => 'User levels management',
 
 # FIXME: Other sites, of course, may have affiliate relations with the booksellers list
 'booksourcetext' => "Below is a list of links to other sites that
diff --git a/maintenance/archives/patch-userlevels.sql b/maintenance/archives/patch-userlevels.sql
new file mode 100644 (file)
index 0000000..98133e9
--- /dev/null
@@ -0,0 +1,19 @@
+-- Oct. 1st 2004 - Ashar Voultoiz
+-- Implement the new sitelevels
+--
+-- This is under development to provide a showcase in HEAD :o)
+
+-- Hold group name and description
+CREATE TABLE `group` (
+  `group_id` int(5) unsigned NOT NULL auto_increment,
+  `group_name` varchar(50) NOT NULL default '',
+  `group_description` varchar(255) NOT NULL default '',
+  PRIMARY KEY  (`group_id`)
+)
+
+-- Relation table between user and groups
+CREATE TABLE `user_groups` (
+       user_id` int(5) unsigned NOT NULL default '0',
+       group_id` int(5) unsigned NOT NULL default '0',
+       PRIMARY KEY  (`user_id`,`group_id`)
+)