Index: datalib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/datalib.php,v
retrieving revision 1.365.2.16
diff -u -r1.365.2.16 datalib.php
--- datalib.php	14 Jun 2007 08:51:57 -0000	1.365.2.16
+++ datalib.php	5 Jul 2007 13:23:23 -0000
@@ -310,6 +310,132 @@
 
 
 /**
+ * Returns a subset of assigned users
+ *
+ * @uses $CFG
+ * @param string $sort A SQL snippet for the sorting criteria to use
+ * @param string $dir A SQL snippet for the dir of the sorting criteria to use
+ * @param string $page Which page?
+ * @param string $recordsperpage Number of assignees per page
+ * @param int $searchrole Role criteria
+ * @param int $searchname User criteria (part of name or idnumber)
+ * @param int $searchinstitution Institution criteria (or part of)
+ * @param int $searchdepartment Department criteria (or part of)
+ * @param int $searchcourse Courses criteria (shortname or list of shortnames)
+ * @param int $searchcategory Category criteria
+ * @param int $searchcity City criteria (or part of)
+ * @return object with records and count  {@link $USER} records AND integer count of the records found
+ */
+
+function get_assignees_listing($sort='lastaccess', $dir='ASC', $page=0, $recordsperpage=99999,
+                           $searchrole='5', $searchname='', $searchinstitution='', $searchdepartment='', $searchcourse='', $searchcategory='', $searchcity='') {
+
+    global $CFG;
+
+    $LIKE      = sql_ilike();
+    $fullname  = sql_fullname();
+
+    $condition = "deleted <> 1";
+    
+    if ($searchrole) {
+        $condition .= " AND (roleid = $searchrole) ";
+    }
+
+    if ($searchname) {
+        $condition .= " AND ($fullname $LIKE '$searchname%' OR u.idnumber $LIKE '$searchname%') ";
+    }
+    
+    if ($searchinstitution) {
+        $institutions = preg_split("/[\s,]+/",$searchinstitution);
+        if (count($institutions) == 1) { // only one institution so we can use LIKE syntax
+            $condition .= " AND (institution $LIKE '$searchinstitution%') ";
+        } else { // a list of institutions
+            foreach ($institutions as $key => $institution) {
+                $institution = "'".$institution."'"; $institutions[$key] = $institution;
+            }
+            $institutions = implode(",",$institutions);
+            $condition .= " AND (institution IN ($institutions)) ";
+        }
+    }
+    
+    if ($searchdepartment) {
+        $departments = preg_split("/[\s,]+/",$searchdepartment);
+        if (count($departments) == 1) { // only one department so we can use LIKE syntax
+            $condition .= " AND (department $LIKE '$searchdepartment%') ";
+        } else { // a list of departments
+            foreach ($departments as $key => $department) {
+                $department = "'".$department."'"; $departments[$key] = $department;
+            }
+            $departments = implode(",",$departments);
+            $condition .= " AND (department IN ($departments)) ";
+        }
+    }
+    
+    if ($searchcourse) {
+        $courses = preg_split("/[\s,]+/",$searchcourse);
+        if (count($courses) == 1) { // only one course so we can use LIKE syntax
+            // $condition .= " AND (shortname $LIKE '$searchcourse%') ";
+            // incompatible when course-level context because several courses can have the same (name) root
+            $condition .= " AND (shortname = '$searchcourse') ";
+        } else { // a list of courses
+            foreach ($courses as $key => $course) {
+                $course = "'".$course."'"; $courses[$key] = $course;
+            }
+            $courses = implode(",",$courses);
+            $condition .= " AND (shortname IN ($courses)) ";
+        }
+    }
+    
+    if ($searchcategory) {
+        if ($category = get_record("course_categories", "id", $searchcategory)) {
+            make_categories_list($searchcategories, $searchparentcategories, $category);
+                // because we need recursivity when more than two levels of category
+            if ($searchcategories) { // in any case, at least the searched category itself
+                $catlisting = "";
+                foreach ($searchcategories as $cat => $path) {
+                    $catlisting .= "$cat, ";
+                }
+            $catlisting = rtrim($catlisting,', ');
+            }
+            $condition .= " AND (cat.id IN ($catlisting)) ";
+        }
+    }
+    
+    if ($searchcity) {
+        $condition .= " AND (city $LIKE '%$searchcity%') ";
+    }
+
+    if ($sort) {
+        $sort = " ORDER BY $sort $dir";
+    }
+    
+    $select = "SELECT DISTINCT u.*";
+
+    $from = "FROM {$CFG->prefix}user u, {$CFG->prefix}role_assignments ra, {$CFG->prefix}course_categories cat, {$CFG->prefix}course c, {$CFG->prefix}context x";
+    $mainwhere = "WHERE u.id = ra.userid AND x.id=ra.contextid AND cat.id=c.category";
+
+    $sqlrequest =   "$select $from $mainwhere AND $condition AND x.instanceid=c.id AND x.contextlevel=50"
+                    // (1: roles in courses)
+                    . " UNION " .
+                    "$select $from $mainwhere AND $condition AND x.instanceid=cat.id AND x.contextlevel=40"
+                    // (2: roles in categories)
+                    . " UNION " .
+                    "$select $from $mainwhere AND $condition AND (LOCATE(CONCAT('/',x.instanceid,'/'), cat.path) > 0) AND x.contextlevel=40"
+                    // (3: roles in subcategories, ie descendant categories of categories in 2)
+                    . " UNION " .
+                    "$select $from $mainwhere AND $condition AND x.contextlevel=10"
+                    // (4: global roles)
+                    . $sort
+                    ;
+    $assignees_records = get_records_sql($sqlrequest);
+    $assignees->count = count($assignees_records);
+    $assignees->records = array_slice($assignees_records, $page, $recordsperpage);
+    // only one query for getting the count AND the records because this query consumes a lot of time even for only counting
+    return $assignees;
+}
+
+
+/**
  * Full list of users that have confirmed their accounts.
  *
  * @uses $CFG
