MDL-11419 - groups: interface enhancements + new features:
authormattc-catalyst <mattc-catalyst>
Mon, 24 Sep 2007 21:55:15 +0000 (21:55 +0000)
committermattc-catalyst <mattc-catalyst>
Mon, 24 Sep 2007 21:55:15 +0000 (21:55 +0000)
    * Display the grouping a course module belongs to on the course page - for course managers only.
    * When adding users to groups, display the groups a user already belongs to.
    * Added an overview report that shows groupings, groups and members for a course.
    * Added a dialogue to automatically create groups and assign members based on either the number of desired groups or the number of desired users per group.

12 files changed:
course/lib.php
group/autogroup.php [new file with mode: 0644]
group/autogroup_form.php [new file with mode: 0644]
group/index.php
group/lib.php
group/members.php
group/overview.php [new file with mode: 0644]
group/tabs.php
lang/en_utf8/group.php
lib/grouplib.php
theme/standard/styles_fonts.css
theme/standard/styles_layout.css

index 3ad961b..197394a 100644 (file)
@@ -1343,6 +1343,8 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
 
 /// Casting $course->modinfo to string prevents one notice when the field is null
     $modinfo = unserialize((string)$course->modinfo);
+    
+    $groupings = groups_get_all_groupings($course->id);
 
     //Acccessibility: replace table with list <ul>, but don't output empty list.
     if (!empty($section->sequence)) {
@@ -1404,6 +1406,9 @@ function print_section($course, $section, $mods, $modnamesused, $absolute=false,
                          '<img src="'.$icon.'"'.
                          ' class="activityicon" alt="'.$mod->modfullname.'" /> '.
                          $instancename.'</a>';
+                    if (!empty($CFG->enablegroupings) && !empty($mod->groupingid) && has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
+                        echo " <span class=\"groupinglabel\"> - ".format_string($groupings[$mod->groupingid]->name).'</span>';
+                    }
                 }
                 if ($usetracking && $mod->modname == 'forum') {
                     $groupmode = groups_get_course_groupmode($course, $mod);
diff --git a/group/autogroup.php b/group/autogroup.php
new file mode 100644 (file)
index 0000000..4e0b3fa
--- /dev/null
@@ -0,0 +1,160 @@
+<?php // $Id$
+/**
+ * Create and allocate users go groups
+ *
+ * @author  Matt Clarkson mattc@catalyst.net.nz
+ * @version 0.0.1
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package groups
+ */
+
+require_once('../config.php');
+require_once('autogroup_form.php');
+
+$courseid = required_param('courseid', PARAM_INT);
+
+if (!$course = get_record('course', 'id',$courseid)) {
+    error('invalidcourse');
+}
+
+// Make sure that the user has permissions to manage groups.
+require_login($course);
+
+$context = get_context_instance(CONTEXT_COURSE, $courseid);
+$sitecontext = get_context_instance(CONTEXT_SYSTEM);
+require_capability('moodle/course:managegroups', $context);
+
+$returnurl = $CFG->wwwroot.'/group/index.php?id='.$course->id;
+
+$strgroups = get_string('groups');
+$strparticipants = get_string('participants');
+$stroverview = get_string('overview', 'group');
+$strgrouping = get_string('grouping', 'group');
+$strgroup = get_string('group', 'group');
+$strnotingrouping = get_string('notingrouping', 'group');
+$strfiltergroups = get_string('filtergroups', 'group');
+
+
+// Print the page and form
+$navlinks = array(array('name'=>$strparticipants, 'link'=>$CFG->wwwroot.'/user/index.php?id='.$courseid, 'type'=>'misc'),
+                  array('name'=>$strgroups, 'link'=>'', 'type'=>'misc'));
+$navigation = build_navigation($navlinks);
+
+
+/// Get applicable roles
+$rolenames = array();
+$avoidroles = array();
+
+if ($roles = get_roles_used_in_context($context, true)) {
+    $canviewroles    = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
+    $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext);
+
+    foreach ($roles as $role) {
+        if (!isset($canviewroles[$role->id])) {   // Avoid this role (eg course creator)
+            $avoidroles[] = $role->id;
+            unset($roles[$role->id]);
+            continue;
+        }
+        if (isset($doanythingroles[$role->id])) {   // Avoid this role (ie admin)
+            $avoidroles[] = $role->id;
+            unset($roles[$role->id]);
+            continue;
+        }
+        $rolenames[$role->id] = strip_tags(role_get_name($role, $context));   // Used in menus etc later on
+    }
+}
+
+/// Create the form
+$editform = new autogroup_form('autogroup.php', array('roles' => $rolenames));
+$editform->set_data(array('courseid' => $courseid,
+                          'seed' => time()));
+
+
+
+/// Handle form submission
+if ($editform->is_cancelled()) {
+    redirect($returnurl);
+} elseif ($data = $editform->get_data()) {
+    
+   /// Allocate members from the selected role to groups
+    if ($data->allocateby == 'random') {
+       $orderby = 'firstname';
+    } else {
+        $orderby = $data->allocateby;
+    }
+    $users = groups_get_potental_members($data->courseid, $data->roleid, $orderby);
+    $usercnt = count($users);
+    
+    if ($data->allocateby == 'random') {
+        srand ($data->seed);
+        shuffle($users);
+    }
+    
+    $groups = array();
+    $i = 0;
+    $cnt = 0;
+    
+    if ($data->groupby == 'groups') {
+       $numgrps = $data->number;
+        $userpergrp = ceil($usercnt/$numgrps);
+    } else {
+       $numgrps = ceil($data->number/$usercnt);
+        $userpergrp = $data->number;
+    }
+    
+    foreach($users as $id => $user) {
+       if (!isset($groups[$i])) { // Create a new group
+               $groups[$i]['name'] = groups_parse_name($data->namingschemegrp['namingscheme'], $i);
+       }
+        @$groups[$i]['members'][] = &$users[$id];
+        $cnt++;
+        if ($cnt == $userpergrp) {
+               $cnt = 0;
+            $i++;
+        }
+    }
+   
+   
+    if (isset($data->preview)) {
+       /// Print the groups preview
+       $preview = '<ul>';
+        foreach ($groups as $group) {
+               $preview .= "<li>$group[name]\n<ul>";
+            foreach ($group['members'] as $member) {
+               $preview .= '<li>'.fullname($member).'</li>';
+            }
+            $preview .= "</ul>\n</li>\n";
+        }
+        $preview .= '</ul>';
+    } else {
+       /// Save the groups data 
+       foreach ($groups as $group) {        
+            $newgroup->timecreated = time();
+            $newgroup->timemodified = $newgroup->timecreated;
+            $newgroup->courseid = $data->courseid;
+            $newgroup->name = $group['name'];
+            $groupid = insert_record('groups', $newgroup);
+            foreach($group['members'] as $user) {
+               $member->groupid = $groupid;
+                $member->userid = $user->id;
+                $member->timeadded = time();
+                insert_record('groups_members', $member);
+            }
+        }
+        redirect($returnurl);
+    }
+
+}
+/// Print header
+print_header_simple($strgroups, ': '.$strgroups, $navigation, '', '', true, '', navmenu($course));
+
+/// Display the form
+$editform->display();
+if(isset($preview)) {
+       print_heading_block(get_string('groupspreview', 'group'));
+    print_box($preview);
+}
+
+print_footer($course);
+?>
\ No newline at end of file
diff --git a/group/autogroup_form.php b/group/autogroup_form.php
new file mode 100644 (file)
index 0000000..0f846d9
--- /dev/null
@@ -0,0 +1,99 @@
+<?php // $Id$
+
+require_once($CFG->dirroot.'/lib/formslib.php');
+
+/// get url variables
+class autogroup_form extends moodleform {
+
+    // Define the form
+    function definition() {
+        global $CFG, $COURSE;
+
+        $mform =& $this->_form;
+
+        $mform->addElement('header', 'autogroup', get_string('autocreategroups', 'group'));
+
+        $options = array(get_string('all'));
+        $options += $this->_customdata['roles'];
+        $mform->addElement('select', 'roleid', get_string('selectfromrole', 'group'), $options);
+        $mform->addRule('roleid', get_string('required'), 'required', null, 'client');
+
+        
+        $options = array('groups' => get_string('groups', 'group'),
+                         'members' => get_string('members', 'group'));
+        $mform->addElement('select', 'groupby', get_string('groupby', 'group'), $options);
+        $mform->addRule('groupby', get_string('required'), 'required', null, 'client');
+        
+        $mform->addElement('text', 'number', get_string('number', 'group'),'maxlength="4" size="4"');
+        $mform->setType('number', PARAM_INT);
+        $mform->addRule('number', null, 'numeric', null, 'client');
+        $mform->addRule('number', get_string('required'), 'required', null, 'client');
+        
+        $options = array('random' => get_string('random', 'group'),
+                         'firstname' => get_string('firstname', 'group'),
+                         'lastname' => get_string('lastname', 'group'));
+                         
+        $mform->addElement('select', 'allocateby', get_string('allocateby', 'group'), $options);
+        $mform->addRule('allocateby', get_string('required'), 'required', null, 'client');
+        
+        $grp[] = $mform->createElement('text', 'namingscheme');
+        $grp[] = $mform->createElement('static', 'namingschemehelp', null, get_string('namingschemehelp', 'group'));
+        $mform->addGroup($grp, 'namingschemegrp', get_string('namingscheme', 'group'), '<br />');
+        
+        $mform->setType('namingschemegrp[namingscheme]', PARAM_RAW);
+        $mform->setDefault('namingschemegrp[namingscheme]', get_string('group', 'group').' @');
+        $mform->addRule('namingschemegrp', get_string('required'), 'required', null, 'client');
+        $mform->setAdvanced('namingschemegrp');
+        
+
+        $mform->addElement('hidden','courseid');
+        $mform->setType('courseid', PARAM_INT);
+        
+        $mform->addElement('hidden','seed');
+        $mform->setType('seed', PARAM_INT);
+        
+        $buttonarray=array();
+        $buttonarray[] = &$mform->createElement('submit', 'preview', get_string('preview'), 'xx');
+        $buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('submit'));
+        $buttonarray[] = &$mform->createElement('cancel');
+        $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
+        $mform->closeHeaderBefore('buttonar');
+    }
+
+
+    function validation($data) {
+       global $CFG, $COURSE;
+        $errors = array();
+
+        if (!$users = groups_get_potental_members($data['courseid'], $data['roleid'])) {         
+            $errors['roleid'] = get_string('nousersinrole', 'group');
+        }
+        $usercnt = count($users);
+        
+       /// Check the number entered is sane     
+        if ($data['groupby'] == 'groups') {
+
+            if ($data['number'] > $usercnt || $data['number'] < 1) {
+               $errors['number'] = get_string('toomanygroups', 'group', $usercnt);
+            }
+        }
+        
+       /// Check the naming scheme 
+        $matchcnt = preg_match_all('/[#@]{1,1}/', $data['namingschemegrp']['namingscheme'], $matches);
+        
+        if ($matchcnt != 1) {
+            $errors['namingschemegrp'] = get_string('badnamingscheme', 'group');
+        }
+        
+        
+        if (count($errors) > 0) {
+            return $errors;
+        } else {
+            return true;
+        }
+        
+    }
+
+}
+
+?>
index f187b27..caddc53 100644 (file)
@@ -68,6 +68,10 @@ switch ($action) {
         redirect('group.php?courseid='.$courseid);
         break;
 
+    case 'showautocreategroupsform':
+        redirect('autogroup.php?courseid='.$courseid);
+        break;        
+
     case 'showgroupsettingsform':
         redirect('group.php?courseid='.$courseid.'&amp;id='.$groupid);
         break;
@@ -180,6 +184,9 @@ echo '<p><input type="submit" '. $deletegroup_disabled . ' name="act_deletegroup
 
 echo '<p><input type="submit" name="act_showcreateorphangroupform" id="showcreateorphangroupform" value="'
         . get_string('creategroup', 'group') . '" /></p>'."\n";
+        
+echo '<p><input type="submit" name="act_showautocreategroupsform" id="showautocreategroupsform" value="'
+        . get_string('autocreategroups', 'group') . '" /></p>'."\n";
 
 echo '</td>'."\n";
 echo '<td>'."\n";
index c0d571a..49f5d85 100644 (file)
@@ -287,6 +287,7 @@ function groups_get_users_not_in_group($courseid, $groupid, $searchtext='') {
     $from   = " FROM {$CFG->prefix}user u
                 INNER JOIN {$CFG->prefix}role_assignments ra ON ra.userid = u.id
                 INNER JOIN {$CFG->prefix}role r ON r.id = ra.roleid";
+                
     $where  = " WHERE ra.contextid ".get_related_contexts_string($context)."
                   AND u.deleted = 0
                   AND ra.roleid in $roleids
@@ -294,8 +295,118 @@ function groups_get_users_not_in_group($courseid, $groupid, $searchtext='') {
                                    FROM {$CFG->prefix}groups_members
                                    WHERE groupid = $groupid)
                   $wheresearch";
+    $groupby = " GROUP BY u.id, u.firstname, u.lastname ";
+    
+    return get_records_sql($select.$from.$where.$groupby);
+}
+
+
+/**
+ * Gets potential group members for grouping
+ * @param int $courseid The id of the course
+ * @param int $roleid The role to select users from
+ * @param string $orderby The colum to sort users by
+ * @return array An array of the users
+ */
+function groups_get_potental_members($courseid, $roleid = null, $orderby = 'lastname') {
+       global $CFG;
+    
+    $context = get_context_instance(CONTEXT_COURSE, $courseid);
+    $sitecontext = get_context_instance(CONTEXT_SYSTEM);
+    $rolenames = array();
+    $avoidroles = array();
+
+    if ($roles = get_roles_used_in_context($context, true)) {
+
+        $canviewroles    = get_roles_with_capability('moodle/course:view', CAP_ALLOW, $context);
+        $doanythingroles = get_roles_with_capability('moodle/site:doanything', CAP_ALLOW, $sitecontext);
+
+        foreach ($roles as $role) {
+            if (!isset($canviewroles[$role->id])) {   // Avoid this role (eg course creator)
+                $avoidroles[] = $role->id;
+                unset($roles[$role->id]);
+                continue;
+            }
+            if (isset($doanythingroles[$role->id])) {   // Avoid this role (ie admin)
+                $avoidroles[] = $role->id;
+                unset($roles[$role->id]);
+                continue;
+            }
+            $rolenames[$role->id] = strip_tags(role_get_name($role, $context));   // Used in menus etc later on
+        }
+    }
+    
+    $select = 'SELECT u.id, u.username, u.firstname, u.lastname, u.idnumber ';
+    $from   = "FROM {$CFG->prefix}user u INNER JOIN
+               {$CFG->prefix}role_assignments r on u.id=r.userid ";
+
+    if ($avoidroles) {
+        $adminroles = 'AND r.roleid NOT IN (';
+        $adminroles .= implode(',', $avoidroles);
+        $adminroles .= ')';
+    } else {
+        $adminroles = '';
+    }
+
+    // we are looking for all users with this role assigned in this context or higher
+    if ($usercontexts = get_parent_contexts($context)) {
+        $listofcontexts = '('.implode(',', $usercontexts).')';
+    } else {
+        $listofcontexts = '('.$sitecontext->id.')'; // must be site
+    }
+    
+    if ($roleid) {
+        $selectrole = " AND r.roleid = $roleid ";
+    } else {
+        $selectrole = " ";
+    }
+    
+    $where  = "WHERE (r.contextid = $context->id OR r.contextid in $listofcontexts)
+               AND u.deleted = 0 $selectrole                 
+               AND u.username != 'guest'
+               $adminroles
+               ";
+    $order = "ORDER BY $orderby ";
+                    
+    return(get_records_sql($select.$from.$where.$order));
+    
+}
 
-    return get_records_sql($select.$from.$where);;
+/**
+ * Parse a group name for characters to replace
+ * @param string $format The format a group name will follow
+ * @param int $groupnumber The number of the group to be used in the parsed format string
+ * @return string the parsed format string
+ */
+function groups_parse_name($format, $groupnumber) {
+    
+    if (strstr($format, '@') !== false) { // Convert $groupnumber to a character series
+       $tmp = $groupnumber;
+        $places = 1;
+        $serial = '';
+        
+        if ($groupnumber > 25) {
+            while (floor($groupnumber / pow(25, $places)) > 0) {
+                  $places++;
+            }
+          
+        } else {
+               $places = 1;
+        }
+        
+        for($i=$places;$i>0;$i--) {
+            if ($i>1) {
+                $serial .= chr(65+floor($tmp/ pow(26, $i)));
+                $tmp -= floor($tmp/ pow(26, $i))*pow(26, $i);
+            } else {
+               $serial .= chr(65+$tmp%26);
+            }             
+        }
+        $str = preg_replace('/[@]/', $serial, $format);
+    } else {
+       $str = preg_replace('/[#]/', $groupnumber+1, $format);
+    }
+    return($str);
 }
 
 ?>
\ No newline at end of file
index e675d24..143681c 100644 (file)
@@ -1,4 +1,4 @@
-<?php
+<?php // $Id$
 /**
  * Add/remove members from group.
  *
@@ -100,9 +100,21 @@ if (!empty($potentialmembers)) {
 if ($potentialmemberscount <=  MAX_USERS_PER_PAGE) {
 
     if ($potentialmembers != false) {
+        // Get other groups user already belongs to
+        $sql = "SELECT u.id AS userid, g.* FROM {$CFG->prefix}user u " .
+                    "INNER JOIN {$CFG->prefix}groups_members gm ON u.id = gm.userid " .
+                    "INNER JOIN {$CFG->prefix}groups g ON gm.groupid = g.id " .
+               "WHERE u.id IN (".implode(',',array_keys($potentialmembers)).") AND g.courseid = {$course->id} ";
+        $rs = get_recordset_sql($sql);
+        $groups = array();
+        $usergroups = array();
+        while ($usergroup =  rs_fetch_next_record($rs)) {
+            $usergroups[$usergroup->userid][$usergroup->id] = $usergroup;
+        }
+        
         // Put the groupings into a hash and sorts them
         foreach ($potentialmembers as $userid => $user) {
-            $nonmembers[$userid] = fullname($user);
+            $nonmembers[$userid] = fullname($user)." (".@count($usergroups[$userid]).")";
         }
         natcasesort($nonmembers);
 
@@ -119,6 +131,7 @@ if ($potentialmemberscount <=  MAX_USERS_PER_PAGE) {
 $strgroups = get_string('groups');
 $strparticipants = get_string('participants');
 $stradduserstogroup = get_string('adduserstogroup', 'group');
+$strusergroupmembership = get_string('usergroupmembership', 'group');
 
 $groupname = format_string($group->name);
 
@@ -130,7 +143,62 @@ $navigation = build_navigation($navlinks);
 
 print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '', '', true, '', user_login_string($course, $USER));
 
+// Print Javascript for showing the selected users group membership
+?>
+<script type="text/javascript">
+//<![CDATA[
+var userSummaries = Array( 
+<?php
+$membercnt = count($nonmembers);
+$i=1;
+foreach ($nonmembers as $userid => $potentalmember) {
+
+    if (isset($usergroups[$userid])) {
+        $usergrouplist = '<ul>';
+    
+        foreach ($usergroups[$userid] as $groupitem) {
+            $usergrouplist .= '<li>'.addslashes(format_string($groupitem->name)).'</li>';
+        }
+        $usergrouplist .= '</ul>';
+    }
+    else {
+       $usergrouplist = '';
+    }
+    echo "'$usergrouplist'";
+    if ($i < $membercnt) {
+       echo ', ';
+    }
+    $i++;
+}
 ?>
+);
+
+function updateUserSummary() {
+
+    var selectEl = document.getElementById('addselect');
+    var summaryDiv = document.getElementById('group-usersummary');
+    var length = selectEl.length;
+    var selectCnt = 0;
+    var selectIdx = -1;
+    
+    for(i=0;i<length;i++) {
+        if (selectEl.options[i].selected) {
+               selectCnt++;
+            selectIdx = i;
+        }
+    }
+
+    if (selectCnt == 1 && userSummaries[selectIdx]) {
+        summaryDiv.innerHTML = userSummaries[selectIdx];
+    } else {
+        summaryDiv.innerHTML = '';
+    }
+    
+    return(true);
+}
+//]]>
+</script>
+
 <div id="addmembersform">
     <h3 class="main"><?php print_string('adduserstogroup', 'group'); echo ": $groupname"; ?></h3>
 
@@ -139,15 +207,17 @@ print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '
     <input type="hidden" name="sesskey" value="<?php p(sesskey()); ?>" />
     <input type="hidden" name="group" value="<?php echo $groupid; ?>" />
 
-    <table summary="" cellpadding="5" cellspacing="0">
+    <table cellpadding="6" class="generaltable generalbox groupmanagementtable boxaligncenter" summary="">
     <tr>
       <td valign="top">
-          <label for="removeselect"><?php print_string('existingmembers', 'group', $groupmemberscount); //count($contextusers) ?></label>
-          <br />
+          <p>
+            <label for="removeselect"><?php print_string('existingmembers', 'group', $groupmemberscount); //count($contextusers) ?></label>
+          </p>
           <select name="removeselect[]" size="20" id="removeselect" multiple="multiple"
                   onfocus="document.getElementById('assignform').add.disabled=true;
                            document.getElementById('assignform').remove.disabled=false;
-                           document.getElementById('assignform').addselect.selectedIndex=-1;">
+                           document.getElementById('assignform').addselect.selectedIndex=-1;"
+                  onclick="this.focus();updateUserSummary();">
           <?php echo $groupmembersoptions ?>
           </select></td>
       <td valign="top">
@@ -161,12 +231,14 @@ print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '
         </p>
       </td>
       <td valign="top">
-          <label for="addselect"><?php print_string('potentialmembers', 'group', $potentialmemberscount); //$usercount ?></label>
-          <br />
+          <p>
+            <label for="addselect"><?php print_string('potentialmembers', 'group', $potentialmemberscount); //$usercount ?></label>
+          </p>
           <select name="addselect[]" size="20" id="addselect" multiple="multiple"
-                  onfocus="document.getElementById('assignform').add.disabled=false;
+                  onfocus="updateUserSummary();document.getElementById('assignform').add.disabled=false;
                            document.getElementById('assignform').remove.disabled=true;
-                           document.getElementById('assignform').removeselect.selectedIndex=-1;">
+                           document.getElementById('assignform').removeselect.selectedIndex=-1;"
+                  onclick="this.focus();updateUserSummary();">
           <?php
             if ($potentialmemberscount > MAX_USERS_PER_PAGE) {
                 echo '<optgroup label="'.get_string('toomanytoshow').'"><option></option></optgroup>'."\n"
@@ -178,7 +250,7 @@ print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '
          </select>
          <br />
          <label for="searchtext" class="accesshide"><?php p($strsearch) ?></label>
-         <input type="text" name="searchtext" id="searchtext" size="30" value="<?php p($searchtext, true) ?>"
+         <input type="text" name="searchtext" id="searchtext" size="21" value="<?php p($searchtext, true) ?>"
                   onfocus ="getElementById('assignform').add.disabled=true;
                             getElementById('assignform').remove.disabled=true;
                             getElementById('assignform').removeselect.selectedIndex=-1;
@@ -191,10 +263,14 @@ print_header("$course->shortname: $strgroups", $course->fullname, $navigation, '
          <input name="search" id="search" type="submit" value="<?php p($strsearch) ?>" />
          <?php
               if (!empty($searchtext)) {
-                  echo '<input name="showall" id="showall" type="submit" value="'.$strshowall.'" />'."\n";
+                  echo '<br /><input name="showall" id="showall" type="submit" value="'.$strshowall.'" />'."\n";
               }
          ?>
        </td>
+       <td valign="top">
+        <p><?php p($strusergroupmembership) ?></p>
+        <div id="group-usersummary"></div>
+       </td>
     </tr>
     <tr><td>
         <input type="submit" name="cancel" value="<?php print_string('backtogroups', 'group'); ?>" />
diff --git a/group/overview.php b/group/overview.php
new file mode 100644 (file)
index 0000000..463f075
--- /dev/null
@@ -0,0 +1,207 @@
+<?php // $Id$
+/**
+ * Print an overview of groupings & group membership
+ *
+ * @author  Matt Clarkson mattc@catalyst.net.nz
+ * @version 0.0.1
+ * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
+ * @package groups
+ */
+require_once('../config.php');
+
+$courseid = required_param('id', PARAM_INT);
+$groupid = optional_param('groupid', 0, PARAM_INT);
+$groupingid = optional_param('groupingid', 0, PARAM_INT);
+
+$returnurl = $CFG->wwwroot.'/group/index.php?id='.$courseid;
+
+if (!$course = get_record('course', 'id',$courseid)) {
+    error('invalidcourse');
+}
+
+// Make sure that the user has permissions to manage groups.
+require_login($course);
+
+$context = get_context_instance(CONTEXT_COURSE, $courseid);
+require_capability('moodle/course:managegroups', $context);
+
+
+
+$strgroups = get_string('groups');
+$strparticipants = get_string('participants');
+$stroverview = get_string('overview', 'group');
+$strgrouping = get_string('grouping', 'group');
+$strgroup = get_string('group', 'group');
+$strnotingrouping = get_string('notingrouping', 'group');
+$strfiltergroups = get_string('filtergroups', 'group');
+$strnogroups = get_string('nogroups', 'group');
+$strnogroupsassigned = get_string('nogroupsassigned', 'group');
+
+// Print the page and form
+$navlinks = array(array('name'=>$strparticipants, 'link'=>$CFG->wwwroot.'/user/index.php?id='.$courseid, 'type'=>'misc'),
+                  array('name'=>$strgroups, 'link'=>'', 'type'=>'misc'));
+$navigation = build_navigation($navlinks);
+
+/// Print header
+print_header_simple($strgroups, ': '.$strgroups, $navigation, '', '', true, '', navmenu($course));
+
+
+if (!empty($CFG->enablegroupings)) {
+    // Add tabs
+    $currenttab = 'overview';
+    require('tabs.php');
+}
+
+$groupings= array();
+
+// Get groupings and child group id's
+if (!empty($CFG->enablegroupings)) {
+       $sql = "SELECT gs.id, gs.name, gg.groupid " .
+           "FROM {$CFG->prefix}groupings gs " .
+                "LEFT JOIN {$CFG->prefix}groupings_groups gg ON gs.id = gg.groupingid " .
+           "WHERE gs.courseid = {$course->id} " .
+           "ORDER BY gs.name, gs.id ";
+
+    $rs = get_recordset_sql($sql);
+    while ($row = rs_fetch_next_record($rs)) {
+        $groupings[] = $row;
+    }
+}
+
+// Get groups & group members
+$sql = "SELECT g.id AS groupid, g.name, u.id AS userid, u.firstname, u.lastname, u.idnumber, u.username " .
+       "FROM {$CFG->prefix}groups g " .
+            "LEFT JOIN {$CFG->prefix}groups_members gm ON g.id = gm.groupid " .
+            "LEFT JOIN {$CFG->prefix}user u ON gm.userid = u.id " .
+       "WHERE g.courseid = {$course->id} " .
+       "ORDER BY g.name, g.id ";
+       
+$rs = get_recordset_sql($sql);
+
+$groupsmembers = array();
+
+// Build a hash of keyed on groupid and userid;
+while ($row = rs_fetch_next_record($rs)) {
+       $groupsmembers[$row->groupid]->name = $row->name;
+    $groupsmembers[$row->groupid]->groupid = $row->groupid;
+    $groupsmembers[$row->groupid]->users[$row->userid] = $row;
+    $groupsmembers[$row->groupid]->printed = false;
+}
+
+if (empty($groupsmembers)) {
+    print_box($strnogroups);
+} else {
+       
+    /// Print overview filter form
+    
+    echo '<form method="get" action="overview.php">';
+    echo "<input type=\"hidden\" name=\"id\" value=\"{$course->id}\" />";
+    echo "<label for=\"groupingselect\">$strfiltergroups $strgrouping </label>";
+    echo '<select id="groupingselect" name="groupingid" onchange="this.parentNode.submit();">';
+    echo '    <option value=""></option>';
+    $lastgroupingid = false;
+    foreach ($groupings as $grouping) {
+        if ($lastgroupingid === false || $lastgroupingid != $grouping->id) {
+            $selected = $grouping->id == $groupingid ? 'selected="selected"':'';
+            echo "<option value=\"{$grouping->id}\" $selected>".format_string($grouping->name)."</option>\n";
+        }
+        $lastgroupingid = $grouping->id;
+    }
+    echo '</select>';
+    
+    echo "<label for=\"groupselect\"> $strgroup </label>";
+    echo '<select id="groupselect" name="groupid" onchange="this.parentNode.submit();">';
+    echo '    <option value=""></option>';
+    $lastgroupid = false;
+    
+    foreach ($groupsmembers as $group) {
+        if ($lastgroupid === false || $lastgroupid != $group->groupid) {
+            $selected = $group->groupid == $groupid ? 'selected="selected"':'';
+            echo "<option value=\"{$group->groupid}\" $selected>".format_string($group->name)."</option>\n";
+        }
+        $lastgroupid = $group->groupid ;
+    }
+    echo '</select>';
+    
+    echo '</form>';
+    
+    
+    /// Print overview
+    print_heading(format_string($course->shortname) .' '.$stroverview, 'center', 3);
+    
+
+    
+    echo '<div id="grouping-groups-overview"><ul>';
+    
+    if (!empty($CFG->enablegroupings) && isset($groupings)) {
+       $lastgroupingid = false;
+       foreach ($groupings as $grouping) {
+               if (!empty($groupingid) && $groupingid != $grouping->id) {
+                continue;
+            }
+            if (!empty($groupid) && $groupid != $grouping->groupid) {
+                continue;
+            }
+               if ($lastgroupingid === false || $lastgroupingid != $grouping->id) {
+                       if($lastgroupingid !== false) {
+                    echo '</ul></li>';
+                }
+    
+                echo "<li>$strgrouping: {$grouping->name}<ul>\n";
+                $lastgroupingid = $grouping->id;
+            }
+            if (isset($groupsmembers[$grouping->groupid])) {
+                echo "<li>{$strgroup}: ".format_string($groupsmembers[$grouping->groupid]->name)."<ul>\n";
+                foreach ($groupsmembers[$grouping->groupid]->users as $user) {
+                    echo "<li><a href=\"{$CFG->wwwroot}/user/view.php?id={$user->userid}\">".fullname($user)."</a></li>\n";
+                }
+                echo "</ul></li>";
+            }
+            else {
+               echo "<li>$strnogroupsassigned</li>";
+            }
+            if (isset($groupsmembers[$grouping->groupid])) {
+                $groupsmembers[$grouping->groupid]->printed = true;
+            }
+       }
+    }
+    if ($lastgroupingid !== false) {
+       echo '</ul></li>';
+    }
+    echo '</ul>';
+    
+    // Print Groups not in a grouping
+    
+    
+    if (empty($groupingid)) {
+        
+        $labelprinted = false;
+        foreach($groupsmembers as $groupmembers) {
+               if ($groupmembers->printed) {
+                       continue;
+               }
+            if (!empty($groupid) && $groupid != $groupmembers->groupid) {
+                continue;
+            }
+            if ($labelprinted === false) {
+               echo "<ul><li>$strnotingrouping<ul>";
+                $labelprinted = true;
+            }
+            
+            echo '<li>'.format_string($groupmembers->name).'<ul>';
+            
+            foreach ($groupmembers->users as $user) {
+                echo "<li><a href=\"{$CFG->wwwroot}/user/view.php?id={$user->userid}\">".fullname($user)."</a></li>\n";
+            } 
+            echo "</ul></li>";         
+        }
+        if ($labelprinted !== false) {
+            echo '</ul></li></ul>';
+        }
+    }
+    echo '</div>';
+}
+
+print_footer($course);
+?>
index 5953184..37ffefc 100644 (file)
@@ -7,7 +7,9 @@
     $row[] = new tabobject('groupings',
                            $CFG->wwwroot.'/group/groupings.php?id='.$courseid,
                            get_string('groupings', 'group'));
-
+    $row[] = new tabobject('overview',
+                           $CFG->wwwroot.'/group/overview.php?id='.$courseid,
+                           get_string('overview', 'group'));
     $tabs[] = $row;
     echo '<div class="groupdisplay">';
     print_tabs($tabs, $currenttab);
index e3cc4bf..57d32eb 100644 (file)
@@ -24,6 +24,7 @@ $string['groups'] = 'Groups';
 $string['group'] = 'Group';
 $string['groupsinselectedgrouping'] = 'Groups in:'; //'selected grouping'
 $string['membersofselectedgroup'] = 'Members of:';
+$string['overview'] = 'Overview';
 
 $string['showgroupsingrouping'] = 'Show groups in grouping';
 $string['showmembersforgroup'] = 'Show members for group';
@@ -103,4 +104,25 @@ $string['groupmembersonlyerror'] = 'Sorry, you must be member of at least one gr
 
 $string['groupaddedsuccesfully'] = 'Group $a added succesfully';
 $string['nopermissionforcreation'] = 'Can\'t create group \"$a\" as you dont have the required permissions';
+
+$string['usergroupmembership'] = 'Selected user\'s membership:';
+$string['filtergroups'] = 'Filter groups by: ';
+$string['nogroups'] = 'There are no groups setup in this course yet';
+
+$string['autocreategroups'] = 'Auto-create groups';
+$string['selectfromrole'] = 'Role to select members from';
+$string['groupby'] = 'Create groups based on the number of ';
+$string['members'] = 'Members per group';
+$string['number'] = 'Number of groups or members per group';
+$string['allocateby'] = 'Allocate members';
+$string['random'] = 'randomly';
+$string['firstname'] = 'alphabetically by first name';
+$string['lastname'] = 'alphabetically by last name';
+$string['namingscheme'] = 'Naming scheme';
+$string['namingschemehelp'] = 'note: Use \'@\' to represent the group letter or \'#\' to represent the group number';
+$string['toomanygroups'] = 'Insufficient users to populate this number of groups - there are only $a users in the selected role.';
+$string['badnamingscheme'] = 'Must contain exactly one \'@\' or one \'#\'  character';
+$string['groupspreview'] = 'Groups preview';
+$string['nousersinrole'] = 'There are no suitable users in the selected role';
+$string['nogroupsassigned'] = 'No groups assigned';
 ?>
index 745b50c..5adde3d 100644 (file)
@@ -106,10 +106,32 @@ function groups_get_all_groups($courseid, $userid=0, $groupingid=0) {
 
     return get_records_sql("SELECT g.*
                               FROM {$CFG->prefix}groups g $userfrom $groupingfrom
-                             WHERE g.courseid = '$courseid' $userwhere $groupingwhere
+                             WHERE g.courseid = $courseid $userwhere $groupingwhere
                           ORDER BY name ASC");
 }
 
+
+/**
+ * Gets array of all groupings in a specified course.
+ * @param int $coursid return only groupings in this with this courseid
+ * @return array | false Returns an array of the group IDs or false if no records
+ * or an error occurred.
+ */
+function groups_get_all_groupings($courseid) {
+    global $CFG;
+
+    // groupings are ignored when not enabled
+    if (empty($CFG->enablegroupings)) {
+        return(false);
+    }
+    return get_records_sql("SELECT *
+                              FROM {$CFG->prefix}groupings
+                             WHERE courseid = $courseid
+                          ORDER BY name ASC");
+}
+
+
+
 /**
  * Determines if the user is a member of the given group.
  *
index d6653d7..1685664 100644 (file)
@@ -460,6 +460,9 @@ h2.headingblock {
   font-style: italic;
 }
 
+.section .groupinglabel {
+  color: #666666;
+}
 
 /***
  *** Doc
index bcd1175..c86c857 100644 (file)
@@ -423,6 +423,45 @@ form.popupform label {
   padding: 5px;
 }
 
+#group-usersummary {
+  width: 14em;
+}
+
+
+#grouping-groups-overview {
+  margin: auto;
+  width: 90%;
+}
+
+#grouping-groups-overview ul {
+  list-style: none;
+  padding-left: 0;
+  margin-left: 0px;
+  font-weight: bold;
+}
+
+/* First level list items i.e. groupings */
+#grouping-groups-overview ul li {
+  padding-bottom: 1.8em;
+}
+
+/* Second level list items i.e. groups */
+#grouping-groups-overview ul li ul li {
+  font-style: italic;
+  font-weight: normal;
+  background-color: #ffffff;
+  border: 1px solid #DDDDDD;
+  padding: 1.1em;
+  margin: 0.1em; 
+}
+
+/* Third level list items i.e. group members */
+#grouping-groups-overview ul li ul li ul li {
+  font-style: normal;
+  border: none;
+  padding: 0;
+}
+
 
 img.icon {
   vertical-align:middle;