From 82fee14ae897137d62aca49258875f0e5083f126 Mon Sep 17 00:00:00 2001
From: nfreear <nfreear>
Date: Fri, 9 Feb 2007 16:04:50 +0000
Subject: [PATCH] Fixes for MDL-8048 groups/AJAX - todo with group/member
 display-names,  sorting etc. (see patch in tracker).

---
 group/groupui/printgrouping.php |  69 ++++++++------
 group/index.php                 |  47 +++++-----
 group/lib/clientlib.js          |   2 +-
 group/lib/groupinglib.php       |  45 ++++++++-
 group/lib/utillib.php           | 159 +++++++++++++++++++++-----------
 5 files changed, 207 insertions(+), 115 deletions(-)

diff --git a/group/groupui/printgrouping.php b/group/groupui/printgrouping.php
index 04e9135031..34da1bf2a4 100644
--- a/group/groupui/printgrouping.php
+++ b/group/groupui/printgrouping.php
@@ -10,14 +10,30 @@
 require_once('../../config.php');
 require_once('../lib.php');
 
+$success = true;
+
 $courseid   = required_param('courseid', PARAM_INT);
 $groupingid = required_param('groupingid', PARAM_INT);
 
+// Get the course information so we can print the header and
+// check the course id is valid
+$course = groups_get_course_info($courseid);
+if (! $course) {
+    $success = false;
+    print_error('invalidcourse');
+}
+
 
-require_login($courseid);
+if ($success) {
+    // Make sure that the user has permissions to manage groups.
+    require_login($courseid);
 
-// confirm_sesskey checks that this is a POST request	
-if (isteacheredit($courseid)) {
+    $context = get_context_instance(CONTEXT_COURSE, $courseid);
+    if (! has_capability('moodle/course:managegroups', $context)) {
+        redirect();
+    }
+
+    //( confirm_sesskey checks that this is a POST request.)	
 
 	// Print the page and form
 	$strgroups = get_string('groups');
@@ -28,43 +44,38 @@ if (isteacheredit($courseid)) {
 	             "-> <a href=\"$CFG->wwwroot/group/groupui/index.php?id=$courseid\">$strgroups</a>".
 	             "-> Display grouping", "", "", true, '', user_login_string($course, $USER));
 
-	$groupingsettings = groups_get_grouping_settings($groupingid);
-
-    if (! isset($groupingsettings->name)) {
+    $groupingname = groups_get_grouping_name($groupingid);
+    if (! $groupingname) {
         print_error('errorinvalidgrouping', 'group', groups_home_url($courseid));
     } else {
        // Print the name of the grouping
-	   $name = $groupingsettings->name;
-	   echo "<h1>$name</h1>\n";
+	   echo "<h1>$groupingname</h1>\n";
     }
 
-	// Get the groups and group members for the grouping
-	$groupids = groups_get_groups_in_grouping($groupingid);
-
-	if ($groupids != false) {
-
-		// Make sure the groups are in the right order 
-		foreach($groupids as $groupid) {
-		    $listgroups[$groupid] = groups_get_group_displayname($groupid);  
-		}
+	// Get the groups and group members for the grouping.
+    if (GROUP_NOT_IN_GROUPING == $groupingid) {
+        $groupids = groups_get_groups_not_in_any_grouping($courseid);
+    } else {
+        $groupids = groups_get_groups_in_grouping($groupingid);
+    }
 
-		natcasesort($listgroups);
+	if ($groupids) {
+		// Make sure the groups are in the right order
+		$group_names = groups_groupids_to_group_names($groupids);
+        
+        // Go through each group in turn and print the group name and then the members
+        foreach ($group_names as $group) {
 
-		// Go through each group in turn and print the group name and then the members	
-		foreach($listgroups as $groupid=>$groupname) {
-			echo "<h2>$groupname</h2>\n";
-			$userids = groups_get_members($groupid);
+			echo "<h2>{$group->name}</h2>\n";
+			$userids = groups_get_members($group->id);
 			if ($userids != false) {
 				// Make sure the users are in the right order
-				unset($listmembers);
-				foreach($userids as $userid) {
-			    	$listmembers[$userid] = groups_get_user_displayname($userid, $courseid);       
-				}
-				natcasesort($listmembers);
+				$user_names = groups_userids_to_user_names($userids, $courseid);
 
                 echo "<ol>\n";
-				foreach($listmembers as $userid=>$name) {
-				    echo "<li>$name</li>\n";
+                foreach ($user_names as $user) {
+
+				    echo "<li>{$user->name}</li>\n";
 				}
                 echo "</ol>\n";
 			}
diff --git a/group/index.php b/group/index.php
index dabbcea7fb..fd9bef51da 100644
--- a/group/index.php
+++ b/group/index.php
@@ -20,9 +20,9 @@ require_js($CFG->wwwroot.'/group/lib/clientlib.js');
 
 
 $success = true;
- 
+
 $courseid   = required_param('id', PARAM_INT);
-$groupingid = optional_param('grouping', -1, PARAM_INT);
+$groupingid = optional_param('grouping', GROUP_NOT_IN_GROUPING, PARAM_INT);
 $groupid    = optional_param('group', false, PARAM_INT);
 $userid     = optional_param('user', false, PARAM_INT);
 
@@ -68,21 +68,23 @@ if ($success) {
 
     switch ($action) {
         case 'ajax_getgroupsingrouping':
-            $groups = groups_groupids_to_groups(groups_get_groups_in_grouping($groupingid));
+            if (GROUP_NOT_IN_GROUPING == $groupingid) {
+                $groupids = groups_get_groups_not_in_any_grouping($courseid);
+            } else {
+                $groupids = groups_get_groups_in_grouping($groupingid);
+            }
+            $group_names = groups_groupids_to_group_names($groupids);
             $json = new Services_JSON();
-            echo $json->encode($groups);
+            echo $json->encode($group_names);
             die;  // Client side JavaScript takes it from here.
 
         case 'ajax_getmembersingroup':
             $members = array();
 
             if ($memberids = groups_get_members($groupid)) {
-                foreach ($memberids as $memberid) {
-                    $member = groups_get_user($memberid);
-                    array_push($members, $member);
-                }
+                $member_names = groups_userids_to_user_names($memberids, $courseid);
                 $json = new Services_JSON();
-                echo $json->encode($members);
+                echo $json->encode($member_names);
             }
             die;  // Client side JavaScript takes it from here.
 
@@ -173,7 +175,7 @@ if ($success) {
     if ($groupingids) {    
         // Put the groupings into a hash and sort them
         foreach($groupingids as $id) {
-            $listgroupings[$id] = groups_get_grouping_displayname($id);
+            $listgroupings[$id] = groups_get_grouping_displayname($id, $courseid);
         }
         natcasesort($listgroupings);
         
@@ -215,21 +217,17 @@ if ($success) {
     }
     if ($groupids) {
         // Put the groups into a hash and sort them
-        foreach($groupids as $id) {
-            $listgroups[$id] = groups_get_group_displayname($id);
-        }
-        
-        natcasesort($listgroups);
+        $group_names = groups_groupids_to_group_names($groupids);
         
         // Print out the HTML
         $count = 1;
-        foreach($listgroups as $id => $name) {
+        foreach ($group_names as $group) {
             $select = '';
-            if ($groupid == $id) { //|| $count <= 1) ??
+            if ($groupid == $group->id) { //|| $count <= 1) ??
                 $select = ' selected="selected"';
-                $sel_groupid = $id;
+                $sel_groupid = $group->id;
             }
-            echo "<option value=\"$id\"$select >$name</option>\n";
+            echo "<option value=\"{$group->id}\"$select>{$group->name}</option>\n";
             $count++;
         }
     }
@@ -254,15 +252,12 @@ if ($success) {
     if (isset($sel_groupid)) {
         $userids = groups_get_members($sel_groupid);
     }
-    if (isset($userids) && is_array($userids)) {       
+    if (isset($userids)) { //&& is_array($userids)        
         // Put the groupings into a hash and sort them
-        foreach($userids as $id) {
-            $listmembers[$id] = groups_get_user_displayname($id, $courseid);       
-        }
-        natcasesort($listmembers);
+        $user_names = groups_userids_to_user_names($userids);
 
-        foreach($listmembers as $id => $name) {
-            echo "<option value=\"$id\">$name</option>\n";
+        foreach ($user_names as $user) {
+            echo "<option value=\"{$user->id}\">{$user->name}</option>\n";
         }
     }
 ?>
diff --git a/group/lib/clientlib.js b/group/lib/clientlib.js
index e4c84d4263..447c74d002 100644
--- a/group/lib/clientlib.js
+++ b/group/lib/clientlib.js
@@ -106,7 +106,7 @@ function UpdatableMembersCombo(wwwRoot, courseId) {
                     for (var i=0; i<members.length; i++) {
                         var optionEl = document.createElement("option");
                         optionEl.setAttribute("value", members[i].id);
-                        optionEl.innerHTML = members[i].firstname+" "+members[i].lastname;
+                        optionEl.innerHTML = members[i].name;
                         selectEl.appendChild(optionEl);
                     }
                 }
diff --git a/group/lib/groupinglib.php b/group/lib/groupinglib.php
index 67e1494a4c..f735ec1640 100644
--- a/group/lib/groupinglib.php
+++ b/group/lib/groupinglib.php
@@ -13,6 +13,7 @@ require_once($CFG->dirroot.'/group/lib/basicgrouplib.php');
 require_once($CFG->dirroot.'/group/db/dbgroupinglib.php');
 
 define('GROUP_NOT_IN_GROUPING', -1);
+define('GROUP_ANY_GROUPING', -2);
 
 /*****************************
         Access/List functions  
@@ -98,8 +99,44 @@ function groups_set_grouping_settings($groupingid, $groupingsettings) {
 	return groups_db_set_grouping_settings($groupingid, $groupingsettings);
 }
 
-// TO DO 
+
+/**
+ * Gets the name of a grouping with a specified ID
+ * @param int $groupid The grouping ID.
+ * @return string The name of the grouping.
+ */
+function groups_get_grouping_name($groupingid) {
+    if (GROUP_NOT_IN_GROUPING == $groupingid) {
+        return get_string('notingrouping', 'group');
+    }
+    elseif (GROUP_ANY_GROUPING == $groupingid) {
+        return get_string('anygrouping', 'group');
+    }
+    $settings = groups_get_grouping_settings($groupingid);
+    if ($settings && isset($settings->name)) {
+        return $settings->name;
+    }
+    return false;
+}
+
+
+/**
+ * Get array of group IDs for the user in a grouping.
+ * @param int $userid
+ * @param int $groupingid
+ * @return array If the user has groups an array of group IDs, else false.
+ */
 function groups_get_groups_for_user_in_grouping($userid, $groupingid) {
+    global $CFG;
+    $sql = "SELECT gg.groupid
+        FROM {$CFG->prefix}groups_groupings_groups gg
+        INNER JOIN {$CFG->prefix}groups_members gm ON gm.groupid = gg.groupid
+        WHERE gm.userid = '$userid'
+        AND gg.groupingid = '$groupingid'";
+    $records = get_records_sql($sql);
+
+//print_object($records);
+    return groups_groups_to_groupids($records); //TODO:check.
 }
 
 /**
@@ -249,13 +286,13 @@ function groups_set_default_grouping_settings($groupingsettings = null) {
 
 
 /**
- * Gets the grouping to use for a particular instance of a module in a course
+ * Gets the grouping ID to use for a particular instance of a module in a course
  * @param int $coursemoduleid The id of the instance of the module in the course
  * @return int The id of the grouping or false if there is no such id recorded 
  * or if an error occurred. 
  */
-function groups_get_grouping_for_coursemodule($coursemoduleid) {
-	return groups_db_get_grouping_for_coursemodule($coursemoduleid);
+function groups_get_grouping_for_coursemodule($coursemodule) {
+	return groups_db_get_grouping_for_coursemodule($coursemodule);
 }
 
 /*****************************
diff --git a/group/lib/utillib.php b/group/lib/utillib.php
index 0203983c8e..a971fa27c2 100644
--- a/group/lib/utillib.php
+++ b/group/lib/utillib.php
@@ -2,10 +2,11 @@
 /**
  * Utility functions for groups.
  *
- * Functions to get information about users and courses that we could do with 
- * that don't use any of the groups and that I can't find anywhere else!
+ * Functions we need independent of groups about users and courses.
+ * And groups utility/ user-interface functions.
  *
  * @copyright &copy; 2006 The Open University
+ * @author N.D.Freear AT open.ac.uk
  * @author J.White AT open.ac.uk
  * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
  * @package groups
@@ -24,74 +25,63 @@ require_once($CFG->libdir.'/moodlelib.php');
  * @param int $groupid The group specified
  * @return int The number of members of the group
  */
-function groups_get_no_group_members($groupid) {
-    $userids = groups_get_members($groupid);
-    if (!$userids) {
-    	$nomembers = 0;
-    } else {
-    	$nomembers = count($userids);
-    }
-
-    return $nomembers;
+function groups_count_group_members($groupid) {
+    return count_records('groups_members', 'groupid ', $groupid);
 }
 
 
 /**
  * Gets the number of groups in a specified grouping
  * @param int $groupingid The grouping specified
+ * @param int $courseid The related course.
  * @return int The number of groups in the grouping
  */
-function groups_get_no_groups_in_grouping($groupingid) {
-    $groupids = groups_get_groups_in_grouping($groupingid);
-    if (!$groupids) {
-    	$nogroups = 0;
+function groups_count_groups_in_grouping($groupingid, $courseid) {
+    if (GROUP_NOT_IN_GROUPING == $groupingid) {
+        $groupids = groups_get_groups_not_in_any_grouping($courseid);
+        return count($groupids);
     } else {
-    	$nogroups = count($groupids);
+        return count_records('groups_groupings_groups', 'groupingid ', $groupingid);
     }
-    return $nogroups;
 }
 
 
 /**
- * Returns the display name of a user. This is the full name which if the user 
- * is a teacher, is prefixed by if the teacher has edit permission and - 
- * otherwise.
- * @param int $userid The id of the user specified
- * @param boolean $teacher True if the user is a teacher, false otherwise
- * @return string The display name of the user 
+ * Returns the display name of a user - the full name of the user 
+ * prefixed by '#' for editing teachers and '-' for teachers.
+ * @param int $userid The ID of the user.
+ * @param int $courseid The ID of the related-course.
+ * @return string The display name of the user.
  */
 function groups_get_user_displayname($userid, $courseid) {
 	if ($courseid == false) {
-		$fullname = false; 
+		$fullname = false;
 	} else {
 		$user = groups_get_user($userid);
 	    $fullname = fullname($user, true);
+        //TODO: isteacher, isteacheredit.
 	    if (isteacher($courseid, $userid)) {
 	        if (isteacheredit($courseid, $userid)) {
 	            $prefix = '# ';
 	        } else {
 	             $prefix = '- ';
 	        }
-	        
 	        $fullname = $prefix.$fullname;
 	    }
 	}
-    
     return $fullname;
 }
 
 
 /**
- * Returns the display name of a group - this is the group name followed by the 
- * number of group members in brackets
- * @param int $groupid The groupid
+ * Returns the display name of a group - the group name followed by 
+ * the number of members in brackets.
+ * @param int $groupid The group ID.
  * @return string The display name of the group
  */
 function groups_get_group_displayname($groupid) {
-	$groupsettings = groups_get_group_settings($groupid);
-    if ($groupsettings) {
-        $groupname = $groupsettings->name;
-        $count = groups_get_no_group_members($groupid);
+	if ($groupname = groups_get_group_name($groupid)) {
+        $count = groups_count_group_members($groupid);
         return "$groupname ($count)"; 
     }
 	return false;
@@ -99,20 +89,15 @@ function groups_get_group_displayname($groupid) {
 
 
 /**
- * Returns the display name of a grouping - this is the grouping name followed 
- * by the number of groups in the
- * grouping in brackets
- * @param int $groupingid The grouping id
+ * Returns the display name of a grouping - the grouping name followed 
+ * by the number of groups in the grouping in brackets.
+ * @param int $groupingid The grouping ID.
+ * @param int $courseid The related course.
  * @return string The display name of the grouping
  */
-function groups_get_grouping_displayname($groupingid) {
-    if (GROUP_NOT_IN_GROUPING == $groupingid) {
-        return get_string('notingrouping', 'group');
-    }    
-	$groupingsettings = groups_get_grouping_settings($groupingid);
-    if ($groupingsettings) {	
-        $groupingname = $groupingsettings->name;
-        $count = groups_get_no_groups_in_grouping($groupingid);
+function groups_get_grouping_displayname($groupingid, $courseid) {
+    if ($groupingname = groups_get_grouping_name($groupingid)) {
+        $count = groups_count_groups_in_grouping($groupingid, $courseid);
         return "$groupingname ($count)";
     }
     return false;
@@ -121,9 +106,9 @@ function groups_get_grouping_displayname($groupingid) {
 
 /**
  * Takes an array of users (i.e of objects) and converts it in the corresponding 
- * array of userids. 
+ * array of user IDs. 
  * @param $users array The array of users
- * @return array The array of user ids, or false if an error occurred 
+ * @return array The array of user IDs, or false if an error occurred 
  */
 function groups_users_to_userids($users) {
     if (! $users) {
@@ -136,6 +121,27 @@ function groups_users_to_userids($users) {
     return $userids;
 }
 
+/**
+ * Get an sorted array of user-id/display-name objects.
+ */
+function groups_userids_to_user_names($userids, $courseid) {
+    if (! $userids) {
+        return array();
+    }
+    $member_names = array();
+    foreach ($userids as $id) {
+        $user = new object;
+        $user->id = $id;
+        $user->name = groups_get_user_displayname($id, $courseid);
+        $member_names[] = $user;
+    }
+    if (! usort($member_names, 'groups_compare_name')) {
+        debug('Error usort [groups_compare_name].');
+    }
+    return $member_names;
+}
+
+
 /**
  * Takes an array of groups (i.e of objects) and converts it to the 
  * corresponding array of group IDs. 
@@ -153,17 +159,14 @@ function groups_groups_to_groupids($groups) {
 	return $groupids;
 }
 
-// @@@ TO DO 
-function groups_groupid_to_group($groupid) {
-}
 
 /**
  * Given an array of group IDs get an array of group objects.
  * TODO: quick and dirty. Replace with SQL?
  * @param $groupids Array of group IDs.
- * @param $courseid Default false, or Course ID.
+ * @param $courseid Default false, or the course ID for backwards compatibility.
  * @param $alldata Default false, or get complete record for group.
- * @param array Array of group objects, with basic or all data.
+ * @return array Array of group objects, with basic or all data.
  */
 function groups_groupids_to_groups($groupids, $courseid=false, $alldata=false) {
     if (! $groupids) {
@@ -176,6 +179,53 @@ function groups_groupids_to_groups($groupids, $courseid=false, $alldata=false) {
     return $groups;
 }
 
+
+/**
+ * Get a sorted array of group-id/display-name objects.
+ */
+function groups_groupids_to_group_names($groupids) {
+    if (! $groupids) {
+        return array();
+    }
+    $group_names = array();
+    foreach ($groupids as $id) {
+        $gname = new object;
+        $gname->id = $id;
+        $gname->name = groups_get_group_displayname($id);
+        $group_names[] = $gname;
+    }
+    if (! usort($group_names, 'groups_compare_name')) {
+        debug('Error usort [groups_compare_name].');
+    }
+    /*// Put the groups into a hash and sort them
+    foreach($groupids as $id) {
+        $listgroups[$id] = groups_get_group_displayname($id);
+    }
+    natcasesort($listgroups);
+
+    $group_names = array();
+    foreach ($listgroups as $id => $name) {
+        $gname = new object;
+        $gname->id = $id;
+        $gname->name = $name;
+        $group_names[] = $gname;
+    }*/
+    return $group_names;
+}
+
+
+/**
+ * Comparison function for 'usort' on objects with a name member.
+ * Equivalent to 'natcasesort'.
+ */
+function groups_compare_name($obj1, $obj2) {
+    if (!$obj1 || !$obj2 || !isset($obj1->name) || !isset($obj2->name)) {
+        debug('Error, groups_compare_name.');
+    }
+    return strcasecmp($obj1->name, $obj2->name);
+}
+
+
 function groups_groupingids_to_groupings($groupingids) {
     if (! $groupingids) {
         return false;
@@ -189,8 +239,7 @@ function groups_groupingids_to_groupings($groupingids) {
 
 /**
  * Gets the user object for a given userid. Can't find a function anywhere to 
- * do this and we need this
- * for fullname()
+ * do this and we need this for fullname()
  * 
  * @param $userid int The userid
  * @return object The corresponding user object, or false if an error occurred
@@ -204,7 +253,7 @@ function groups_get_user($userid) {
  * Gets the course information object for a given course id  
  * @param $courseid int The course id
  * @return object The course info object, or false if an error occurred. 
- * @@@ TO DO - need to put the database bit into a db file 
+ * TODO: need to put the database bit into a db file 
  */
 function groups_get_course_info($courseid){
 	if (!$courseid) {
-- 
2.39.5