]> git.mjollnir.org Git - moodle.git/commitdiff
metacourse sync now uses roles, I will continue with fixing of GUIs tomorrow
authorskodak <skodak>
Sun, 17 Sep 2006 22:21:37 +0000 (22:21 +0000)
committerskodak <skodak>
Sun, 17 Sep 2006 22:21:37 +0000 (22:21 +0000)
lib/accesslib.php
lib/moodlelib.php

index 1556daba20850d3df4ef669a4c6782d2e5219b3e..d7de7c5449436b5518f9047892c938493a51a7d9 100755 (executable)
@@ -1417,10 +1417,7 @@ function role_assign($roleid, $userid, $groupid, $contextid, $timestart=0, $time
     if ($success and $context->aggregatelevel == CONTEXT_COURSE) {
         if ($parents = get_records('course_meta', 'child_course', $context->instanceid)) {
             foreach ($parents as $parent) {
-                if ($metacontext = get_context_instance(CONTEXT_COURSE, $parent->parent_course)) {
-                    // try it even when something failed
-                    $success = $success and role_assign($roleid, $userid, $groupid, $metacontext->id, $timestart, $timeend, $hidden, $enrol);
-                }
+                sync_metacourse($parent->parent_course);
             }
         }
     }
@@ -1487,13 +1484,10 @@ function role_unassign($roleid=0, $userid=0, $groupid=0, $contextid=0) {
                             }
                         }
                     }
-                    //unassign roles in metacourses too
+                    //unassign roles in metacourses if needed
                     if ($parents = get_records('course_meta', 'child_course', $context->instanceid)) {
                         foreach ($parents as $parent) {
-                            if ($metacontext = get_context_instance(CONTEXT_COURSE, $parent->parent_course)) {
-                                // ignore errors in metacourses in case they are not properly synchronized
-                                role_unassign($roleid, $userid, $groupid, $metacontext->id);
-                            }
+                            sync_metacourse($parent->parent_course);
                         }
                     }
                 }
index 0c3b6c93a7ecf37da82d5c84c3564680f46e7711..db5dc7519853986566894bc04a71791d34ae84a3 100644 (file)
@@ -1813,97 +1813,98 @@ function sync_metacourses() {
 
     global $CFG;
 
-    if (!$courses = get_records_sql("SELECT DISTINCT parent_course,1 FROM {$CFG->prefix}course_meta")) {
+    if (!$courses = get_records('course', 'metacourse', 1)) {
         return;
     }
 
     foreach ($courses as $course) {
-        sync_metacourse($course->parent_course);
+        sync_metacourse($course);
     }
 }
 
-
 /**
  * Goes through all enrolment records for the courses inside the metacourse and sync with them.
  */
 
-function sync_metacourse($metacourseid) {
-
+function sync_metacourse($course) {
     global $CFG;
+    $status = true;
 
-    if (!$metacourse = get_record("course","id",$metacourseid)) {
-        return false;
-    }
-
-    if (count_records('course_meta','parent_course',$metacourseid) == 0) {
-        // if there are no child courses for this meta course, nuke the enrolments
-        if ($enrolments = get_records('user_students','course',$metacourseid,'','userid,1')) {
-            foreach ($enrolments as $enrolment) {
-                unenrol_student($enrolment->userid,$metacourseid);
-            }
+    if (!is_object($course)) {
+        if (!$course = get_record('course', 'id', $course)) {
+            return false; // invalid course id
         }
-        return true;
     }
-
-    // first get the list of child courses
-    $c_courses = get_records('course_meta','parent_course',$metacourseid);
-    $instr = '';
-    foreach ($c_courses as $c) {
-        $instr .= $c->child_course.',';
+    
+    if (empty($course->metacourse)) {
+        return false; // can not sync normal course or not $course object
     }
-    $instr = substr($instr,0,-1);
 
-    // now get the list of valid enrolments in the child courses
-    $sql = 'SELECT DISTINCT userid,1 FROM '.$CFG->prefix.'user_students WHERE course IN ('.$instr.')';
-    $enrolments = get_records_sql($sql);
+    $context = get_context_instance(CONTEXT_COURSE, $course->id); // SITEID can not be a metacourse
 
-    // put it into a nice array we can happily use array_diff on.
-    $ce = array();
-    if (!empty($enrolments)) {
-        foreach ($enrolments as $en) {
-            $ce[] = $en->userid;
-        }
+    if (!$roles = get_records('role')) {
+        return false; // hmm, there should be always at least one role
+    }
+    
+    // always keep metacourse managers
+    if ($users = get_users_by_capability($context, 'moodle/course:managemetacourses')) {
+        $managers = array_keys($users);
+    } else {
+        $managers = array();
     }
 
-    // now get the list of current enrolments in the meta course.
-    $sql = 'SELECT userid,1 FROM '.$CFG->prefix.'user_students WHERE course = '.$metacourseid;
-    $enrolments = get_records_sql($sql);
-
-    $me = array();
-    if (!empty($enrolments)) {
-        foreach ($enrolments as $en) {
-            $me[] = $en->userid;
+    // find all role users in child courses + build list of current metacourse assignments
+    $in_childs = array(); 
+    foreach ($roles as $role) {
+        if ($users = get_role_users($role->id, $context, false)) {
+            $current[$role->id] = array_keys($users);
+        } else {
+            $current[$role->id] = array();
         }
+        $in_childs[$role->id] = array(); //initialze array
     }
+    if ($children = get_records('course_meta', 'parent_course', $course->id)) {
+        foreach ($children as $child) {
+            $ch_context = get_context_instance(CONTEXT_COURSE, $child->child_course);
+            foreach ($roles as $role) {
+                if ($users = get_role_users($role->id, $ch_context, false)) {
 
-    $enrolmentstodelete = array_diff($me,$ce);
-    $userstoadd = array_diff($ce,$me);
-
-    foreach ($enrolmentstodelete as $userid) {
-        unenrol_student($userid,$metacourseid);
+                    $users = array_keys($users);
+                    $in_childs[$role->id] = array_merge($in_childs[$role->id], $users);
+                }
+            }
+        }
     }
-    foreach ($userstoadd as $userid) {
-        enrol_student($userid,$metacourseid,0,0,'metacourse');
+    
+    foreach ($roles as $role) {
+        //clean up the duplicates from cuncurrent assignments in child courses
+        $in_childs[$role->id] = array_unique($in_childs[$role->id]);
+        //make a list of all potentially affected users
     }
 
-    // and next make sure that we have the right start time and end time (ie max and min) for them all.
-    if ($enrolments = get_records('user_students','course',$metacourseid,'','id,userid')) {
-        foreach ($enrolments as $enrol) {
-            if ($maxmin = get_record_sql("SELECT min(timestart) AS timestart, max(timeend) AS timeend
-               FROM {$CFG->prefix}user_students u,
-                    {$CFG->prefix}course_meta mc
-               WHERE u.course = mc.child_course
-               AND userid = $enrol->userid
-               AND mc.parent_course = $metacourseid")) {
-                $enrol->timestart = $maxmin->timestart;
-                $enrol->timeend = $maxmin->timeend;
-                $enrol->enrol = 'metacourse'; // just in case it wasn't there earlier.
-                update_record('user_students',$enrol);
+    foreach ($roles as $role) {
+        foreach ($current[$role->id] as $userid) {
+            if (in_array($userid, $in_childs[$role->id])) {
+                // ok - no need to change anything
+                unset($in_childs[$role->id][array_search($userid, $in_childs[$role->id])]);
+            } else {
+                // unassign if not metacourse manager
+                if (!in_array($userid, $managers)) {
+                    //echo "unassigning uid: $userid from role: $role->id in context: $context->id <br>\n";
+                    role_unassign($role->id, $userid, 0, $context->id);
+                }
             }
         }
+        // now assign roles to those left in $in_childs  
+        foreach ($in_childs[$role->id] as $userid) {
+            //echo "  assigning uid: $userid from role: $role->id in context: $context->id <br>\n";
+            role_assign($role->id, $userid, 0, $context->id);
+        }        
     }
-    return true;
 
+// TODO: finish timeend and timestart
+// maybe we could rely on cron job to do the cleaning from time to time
+    return true;
 }
 
 /**