]> git.mjollnir.org Git - moodle.git/commitdiff
Initial checkin for new meta courses feature. Please test!
authormjollnir_ <mjollnir_>
Mon, 24 Jan 2005 22:21:28 +0000 (22:21 +0000)
committermjollnir_ <mjollnir_>
Mon, 24 Jan 2005 22:21:28 +0000 (22:21 +0000)
See http://moodle.org/mod/forum/discuss.php?d=17269 for description.

15 files changed:
admin/cron.php
blocks/admin/block_admin.php
course/edit.html
course/edit.php
course/lib.php
course/student.php
lang/en/help/enrolperiod.html
lang/en/moodle.php
lib/datalib.php
lib/db/mysql.php
lib/db/mysql.sql
lib/db/postgres7.php
lib/db/postgres7.sql
lib/moodlelib.php
version.php

index 6d7608f6ed3c27bbaa76cd0d8842d213bc60eda6..c0c759c403be2b609ff2af9478ebc9957b42e722 100644 (file)
         }
         flush();
 
+        sync_metacourses();
+
     } // End of occasional clean-up tasks
 
     if (file_exists("$CFG->dataroot/cronextra.php")) {
index 49213c8e3b9bd9cfe61a23486de9b463a4e415d9..2535fe2db3353482daac266fa5fe1c1849951955 100644 (file)
@@ -103,10 +103,15 @@ class block_admin extends block_base {
 
                 if (!$course->students) {
                     $course->students = get_string('defaultcoursestudents');
+                } 
+                if (!$course->meta_course) {
+                    $this->content->items[]='<a href="student.php?id='.$this->instance->pageid.'">'.$course->students.'...</a>';
+                    $this->content->icons[]='<img src="'.$CFG->pixpath.'/i/users.gif" height="16" width="16" alt="" />';
+                }
+                else {
+                    $this->content->items[]='<a href="importstudents.php?id='.$this->instance->pageid.'">'.$course->students.'...</a>';
+                    $this->content->icons[]='<img src="'.$CFG->pixpath.'/i/users.gif" height="16" width="16" alt="">';
                 }
-                $this->content->items[]='<a href="student.php?id='.$this->instance->pageid.'">'.$course->students.'...</a>';
-                $this->content->icons[]='<img src="'.$CFG->pixpath.'/i/users.gif" height="16" width="16" alt="" />';
-
                 $this->content->items[]='<a href="'.$CFG->wwwroot.'/backup/backup.php?id='.$this->instance->pageid.'">'.get_string('backup').'...</a>';
                 $this->content->icons[]='<img src="'.$CFG->pixpath.'/i/backup.gif" height="16" width="16" alt="" />';
 
index 6380029631f470bf4ab3bf8f42b6083166d18a76..317b5160cbe5c934bd8d178034c096d3658cac2d 100644 (file)
@@ -15,6 +15,9 @@
     if (!isset($form->enrolperiod)) {
         $form->enrolperiod = 0;
     }
+    if (!isset($form->meta_course)) {
+        $form->meta_course = 0;
+    }
 ?>
 <form method="post" action="edit.php" name="form">
 <table cellpadding="9" cellspacing="0" >
     ?>
     </td>
 </tr>
+<tr valign="top">
+  <td align="right"><p><?php print_string("managemeta") ?>:</td>
+    <td>
+      <?php 
+      if (empty($disable_meta)) {
+          $meta[0] = get_string('no');
+          $meta[1] = get_string('yes');
+          choose_from_menu($meta,"meta_course",$form->meta_course,"","","");
+      } else {
+          echo ((empty($form->meta_course)) ? get_string("no") : get_string("yes"));
+         echo " - $disable_meta ";
+      } ?>&nbsp;<?php print_string("managemetaexplan"); ?>
+    </td>
+</tr>
 <tr>
     <td></td>
     <td><input type="submit" value="<?php  print_string("savechanges") ?>" /></td>
index edfa2ccf72f1a38e998c5d373b615c7a49faea55..83e728cedf90681d890a9c7b41b74f001e4f6674 100644 (file)
@@ -9,6 +9,8 @@
     $category = (int)optional_param('category', 0);   // possible default category
 
     require_login();
+   
+    $disable_meta = false;
 
     if ($id) {
         if (! $course = get_record("course", "id", $id)) {
         if (!isteacheredit($course->id)) {
             error("You do not currently have editing privileges!");
         }
+        
+        if (course_in_meta($course)) {
+            $disable_meta = get_string('metaalreadyinmeta');
+        }
+        else if ($course->meta_course) {
+            if (count_records("meta_course","parent_course",$course->id) > 0) {
+                $disable_meta = get_string('metaalreadyhascourses');
+            }
+        }
+        else {
+            if (count_records("user_students","course",$course->id) > 0) {
+                $disable_meta = get_string('metaalreadyhasenrolments');
+            }
+        }
     } else {  // Admin is creating a new course
 
         if (!iscreator()) {
index 6b74205d1c024b6be481d2c922cba0b1ca2ae547..2bcfa7aa359827ac397701f6a83f355c369c43cc 100644 (file)
@@ -1867,4 +1867,26 @@ function make_editing_buttons($mod, $absolute=false, $moveselect=true, $indent=-
            " alt=\"$str->delete\" /></a>$hideshow$groupmode";
 }
 
+/**
+ * given a course object with shortname & fullname, this function will 
+ * truncate the the number of chars allowed and add ... if it was too long
+ */
+function course_format_name ($course,$max=100) {
+    
+    $str = $course->shortname.': '.$course->fullname;
+    if (strlen($str) <= $max) {
+        return $str;
+    }
+    else {
+        return substr($str,0,$max-3).'...';
+    }
+}
+
+/**
+ * This function will return true if the given course is a child course at all
+ */
+function course_in_meta ($course) {
+    return record_exists("meta_course","child_course",$course->id);
+}
+
 ?>
index 7e074998fd211b33044a2e60ccda254a57d2bac2..666a64063321ca4db0755574015d1d769d71c995 100644 (file)
         error("Course ID was incorrect (can't find it)");
     }
 
+    if ($course->meta_course) {
+        redirect("$CFG->wwwroot/course/importstudents.php?id=$course->id");
+    }
+
     require_login($course->id);
 
     if (!isteacheredit($course->id)) {
index c55f4aec63d9c6bc62e8a2433ff7efc2fdef7c5b..33f993f1c1b7d9e3808236dc140e1f4724bd935d 100644 (file)
@@ -11,3 +11,5 @@
    in this course until they are manually unenrolled or the 
    clean-up function to remove defunct students takes effect. </p>
 
+<p>If you have selected to manage this course as a meta course,
+   your enrolment period will not be used.</p>
\ No newline at end of file
index e0589fd0336801840379806cdb30e5d14d48a5de..fc20a90a6f96f82d8963aaf79cf244af8679c96c 100644 (file)
@@ -590,6 +590,7 @@ $string['htmleditordisabledbrowser'] = 'The HTML editor is unavailable because y
 $string['htmlformat'] = 'Pretty HTML format';
 $string['icqnumber'] = 'ICQ number';
 $string['idnumber'] = 'ID number';
+$string['importmetacoursenote'] = 'Use this form to add courses to your meta course (this will import the enrolments)';
 $string['inactive'] = 'Inactive';
 $string['include'] = 'Include';
 $string['includeallusers'] = 'Include All Users';
@@ -671,6 +672,9 @@ $string['makeeditable'] = 'If you make \'$a\' editable by the web server process
 $string['manageblocks'] = 'Blocks';
 $string['managedatabase'] = 'Database';
 $string['managefilters'] = 'Filters';
+$string['managemeta'] = 'Is this a meta course?';
+$string['managemetaexplan'] = '(This means that enrolments are inherited from other courses)';
+$string['managemetadisabled'] = 'This is disabled because this course is already in a meta course';
 $string['managemodules'] = 'Modules';
 $string['markedthistopic'] = 'This topic is highlighted as the current topic';
 $string['markthistopic'] = 'Highlight this topic as the current topic';
@@ -679,6 +683,16 @@ $string['maximumgrade'] = 'Maximum grade';
 $string['maximumshort'] = 'Max';
 $string['maximumupload'] = 'Maximum upload size';
 $string['maxsize'] = 'Max size: $a';
+$string['metaassigncourses'] = 'Assign courses';
+$string['metaalreadycourses'] = 'Courses already assigned';
+$string['metaalreadyhascourses'] = 'This meta course already has child courses.';
+$string['metaalreadyhasenrolments'] = 'This course already has normal enrolments.';
+$string['metaalreadyinmeta'] = 'This course is already part of a meta course.';
+$string['metanoalreadycourses'] = 'No courses already assigned';
+$string['metapotentialcourses'] = 'Courses available';
+$string['metanopotentialcourses'] = 'No courses available';
+$string['metaaddcourse'] = 'Add this course';
+$string['metaremovecourse'] = 'Remove this course';
 $string['min'] = 'min';
 $string['mins'] = 'mins';
 $string['minutes'] = 'minutes';
index bcea6cc210c89f9fee89826907141397dae54538..ab54b3d5bbeda78a2aa245953569adf6c688f8c6 100644 (file)
@@ -1297,6 +1297,34 @@ function get_creators() {
                              ORDER BY u.id ASC");
 }
 
+function get_courses_in_metacourse($metacourseid) {
+    global $CFG;
+
+    $sql = "SELECT c.id,c.shortname,c.fullname FROM {$CFG->prefix}course c, {$CFG->prefix}meta_course mc WHERE mc.parent_course = $metacourseid
+        AND mc.child_course = c.id";
+
+    return get_records_sql($sql);
+}
+
+function get_courses_notin_metacourse($metacourseid,$count=false) {
+
+    global $CFG;
+
+    $site = get_site(); // we don't want the site course in here.
+
+    if ($count) {
+        $sql  = "SELECT COUNT(c.id)";
+    }
+    else {
+        $sql = "SELECT c.id,c.shortname,c.fullname";
+    }
+    $sql .= " FROM {$CFG->prefix}course c LEFT  JOIN {$CFG->prefix}meta_course mc ON mc.child_course = c.id
+     WHERE (mc.parent_course IS NULL OR mc.parent_course != $metacourseid) AND c.id != $metacourseid AND c.id != $site->id";
+
+    return get_records_sql($sql);
+}
+
+
 /**
  * Returns $user object of the main teacher for a course
  *
index e6eef77ce2ad18422aa0b79482c5a3ea5bf6ba32..6f19eb0720a19d0d6a2aa9fb785d3b8ba42c101d 100644 (file)
@@ -1102,9 +1102,23 @@ function main_upgrade($oldversion=0) {
             }
         }
     }
+    
 
-    return $result;
+    if ($oldversion < 2005012500) { 
+        // add new table for meta courses.
+        modify_database("","CREATE TABLE `prefix_meta_course` (
+            `id` int(1) unsigned NOT NULL auto_increment,
+            `parent_course` int(10) NOT NULL default 0,
+            `child_course` int(10) NOT NULL default 0,
+            PRIMARY KEY (`id`),
+            KEY `parent_course` (parent_course),
+            KEY `child_course` (child_course)
+        );");
+        // add flag to course field
+        table_column('course','','meta_course','integer','1','','0','not null');
+    }
 
+    return $result;
 }
 
 ?>
index dacedc610153d906dafae2ad5ebf94f2806ca5dd..369c1cefd61f3217692d5cd530cb67dff8ab6a5b 100644 (file)
@@ -59,6 +59,7 @@ CREATE TABLE `prefix_course` (
   `cost` varchar(10) NOT NULL default '',
   `timecreated` int(10) unsigned NOT NULL default '0',
   `timemodified` int(10) unsigned NOT NULL default '0',
+  `meta_course` int(1) unsigned NOT NULL default '0',
   PRIMARY KEY  (`id`),
   KEY `category` (`category`),
   KEY `idnumber` (`idnumber`),
@@ -549,6 +550,16 @@ CREATE TABLE `prefix_user_coursecreators` (
   KEY `userid` (`userid`)
 ) TYPE=MyISAM COMMENT='One record per course creator';
 
+
+CREATE TABLE `prefix_meta_course` (
+ `id` int(1) unsigned NOT NULL auto_increment,
+ `parent_course` int(10) NOT NULL default 0,
+ `child_course` int(10) NOT NULL default 0,
+ PRIMARY KEY (`id`),
+ KEY `parent_course` (parent_course),
+ KEY `child_course` (child_course)
+);
+
 INSERT INTO prefix_log_display VALUES ('user', 'view', 'user', 'CONCAT(firstname," ",lastname)');
 INSERT INTO prefix_log_display VALUES ('course', 'user report', 'user', 'CONCAT(firstname," ",lastname)');
 INSERT INTO prefix_log_display VALUES ('course', 'view', 'course', 'fullname');
index 9367c836c71217860060ff70781298afa5b3318d..a98b1d1f58e68e49e0ad7a441d6b206a061118f1 100644 (file)
@@ -878,6 +878,18 @@ function main_upgrade($oldversion=0) {
         }
     }
 
+    if ($oldversion < 2005012500) { // add new table for meta courses.
+        modify_database("","CREATE TABLE prefix_meta_course (
+                id SERIAL primary key,
+                parent_course integer NOT NULL,
+                child_course integer NOT NULL
+             );");
+
+        modify_database("","CREATE INDEX prefix_meta_course_parent_idx ON prefix_meta_course (parent_course);");
+        modify_database("","CREATE INDEX prefix_meta_course_child_idx ON prefix_meta_course (child_course);");
+        table_column('course','','meta_course','integer','1','','0','not null');
+    }
+
     return $result;
 }
 
index 25a72683d673d45bf0417d865fede14eb429aea4..9cf09a459cc50f90a7dc7cc55fd503209f02fe1f 100644 (file)
@@ -36,7 +36,8 @@ CREATE TABLE prefix_course (
    lang varchar(10) NOT NULL default '',
    cost varchar(10) NOT NULL default '',
    timecreated integer NOT NULL default '0',
-   timemodified integer NOT NULL default '0'
+   timemodified integer NOT NULL default '0',
+   meta_course integer NOT NULL default '0'
 );
 
 CREATE UNIQUE INDEX prefix_course_category_sortorder_uk ON prefix_course (category,sortorder);
@@ -380,6 +381,15 @@ CREATE TABLE prefix_user_coursecreators (
    userid int8  NOT NULL default '0'
 );
 
+CREATE TABLE prefix_meta_course (
+       id SERIAL primary key,
+       parent_course integer NOT NULL,
+       child_course integer NOT NULL
+);
+
+CREATE INDEX prefix_meta_course_parent_idx ON prefix_meta_course (parent_course);
+CREATE INDEX prefix_meta_course_child_idx ON prefix_meta_course (child_course);
+
 INSERT INTO prefix_log_display VALUES ('user', 'view', 'user', 'firstname||\' \'||lastname');
 INSERT INTO prefix_log_display VALUES ('course', 'user report', 'user', 'firstname||\' \'||lastname');
 INSERT INTO prefix_log_display VALUES ('course', 'view', 'course', 'fullname');
index c99196702f1513a15631d924b00239c9cb2ddf2a..f09dea45a55189f54d6a56cd73217366e1c4f38d 100644 (file)
@@ -1041,6 +1041,128 @@ function check_for_restricted_user($username=NULL, $redirect='') {
     }
 }
 
+function sync_metacourses() {
+
+    global $CFG;
+
+    if (!$courses = get_records_sql("SELECT DISTINCT parent_course,1 FROM {$CFG->prefix}meta_course")) {
+        return;
+    }
+    
+    foreach ($courses as $course) {
+        sync_metacourse($course->parent_course);
+    }
+}
+
+
+/**
+ * Goes through all enrolment records for the courses inside the metacourse and sync with them.
+ */ 
+
+function sync_metacourse($metacourseid) {
+
+    global $CFG;
+
+    if (!$metacourse = get_record("course","id",$metacourseid)) {
+        return false;
+    }
+
+
+    if (count_records('meta_course','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);
+            }
+        }
+        return true;
+    }
+
+
+    // this will return a list of userids from user_student for enrolments in the metacourse that shouldn't be there.
+    $sql = "SELECT DISTINCT parent.userid,1 
+            FROM {$CFG->prefix}meta_course meta 
+              JOIN {$CFG->prefix}user_students parent 
+                ON meta.parent_course = parent.course 
+                AND meta.parent_course = $metacourseid
+              LEFT JOIN {$CFG->prefix}user_students child
+                ON meta.child_course = child.course 
+                WHERE child.course IS NULL";
+
+    if ($enrolmentstodelete = get_records_sql($sql)) {
+        foreach ($enrolmentstodelete as $enrolment) {
+            unenrol_student($enrolment->userid,$metacourseid); // doing it this way for forum subscriptions etc.
+        }
+    }
+
+
+    // this will return a list of userids that need to be enrolled in the metacourse
+    $sql = "SELECT DISTINCT child.userid,1 
+            FROM {$CFG->prefix}meta_course meta 
+              JOIN {$CFG->prefix}user_students child 
+                 ON meta.child_course = child.course 
+                 AND meta.parent_course = $metacourseid
+              LEFT JOIN {$CFG->prefix}user_students parent 
+                 ON meta.parent_course = parent.course 
+                 WHERE parent.course IS NULL";
+
+    if ($userstoadd = get_records_sql($sql)) {
+        foreach ($userstoadd as $user) {
+            enrol_student($user->userid,$metacourseid);
+        }
+    }
+    
+    // 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 mdl_user_students u JOIN mdl_meta_course mc ON u.course = mc.child_course WHERE userid = $enrol->userid
+               AND mc.parent_course = $metacourseid")) {
+                $enrol->timestart = $maxmin->timestart;
+                $enrol->timeend = $maxmin->timeend;
+                update_record('user_students',$enrol);
+            }
+        }
+    }
+    return true;
+}
+
+/** 
+ * Adds a record to the metacourse table and calls sync_metacoures
+ */
+function add_to_metacourse ($metacourseid, $courseid) {
+    if (!$metacourse = get_record("course","id",$metacourseid)) {
+        return false;
+    }
+    
+    if (!$course = get_record("course","id",$courseid)) {
+        return false;
+    }
+
+    if (!$record = get_record("meta_course","parent_course",$metacourseid,"child_course",$courseid)) {
+        $rec->parent_course = $metacourseid;
+        $rec->child_course = $courseid;
+        if (!insert_record('meta_course',$rec)) {
+            return false;
+        }
+        return sync_metacourse($metacourseid);
+    }
+    return true;
+   
+}
+
+/** 
+ * Removes the record from the metacourse table and calls sync_metacourse
+ */
+function remove_from_metacourse($metacourseid, $courseid) {
+
+    if (delete_records('meta_course','parent_course',$metacourseid,'child_course',$courseid)) {
+        return sync_metacourse($metacourseid);
+    }
+    return false;
+}
+
+
 /**
  * Determines if a user an admin
  *
@@ -1640,6 +1762,12 @@ function enrol_student($userid, $courseid, $timestart=0, $timeend=0, $enrol='man
     if (!$user = get_record('user', 'id', $userid)) {        // Check user
         return false;
     }
+    // enrol the student in any parent meta courses...
+    if ($parents = get_records('meta_course','child_course',$courseid)) {
+        foreach ($parents as $parent) {
+            enrol_student($userid, $parent->parent_course,$timestart,$timeend,$enrol);
+        }
+    }
     if ($student = get_record('user_students', 'userid', $userid, 'course', $courseid)) {
         $student->timestart = $timestart;
         $student->timeend = $timeend;
@@ -1682,6 +1810,12 @@ function unenrol_student($userid, $courseid=0) {
                 delete_records('groups_members', 'groupid', $group->id, 'userid', $userid);
             }
         }
+        // enrol the student in any parent meta courses...
+        if ($parents = get_records('meta_course','child_course',$courseid)) {
+            foreach ($parents as $parent) {
+                unenrol_student($userid, $parent->parent_course);
+            }
+        }
         return delete_records('user_students', 'userid', $userid, 'course', $courseid);
 
     } else {
@@ -2009,6 +2143,24 @@ function remove_course_contents($courseid, $showfeedback=true) {
         $result = false;
     }
 
+    if ($course->meta_course) {
+        delete_records("meta_course","parent_course",$course->id);
+        sync_metacourse($course->id); // have to do it here so the enrolments get nuked. sync_metacourses won't find it without the id.
+        if ($showfeedback) {
+            notify("$strdeleted meta_course");
+        }
+    }
+    else {
+        if ($parents = get_records("meta_course","child_course",$course->id)) {
+            foreach ($parents as $parent) {
+                remove_from_metacourse($parent->parent_course,$parent->child_course); // this will do the unenrolments as well.
+            }
+            if ($showfeedback) {
+                notify("$strdeleted meta_course");
+            }
+        }
+    }
+
     return $result;
 
 }
index e2a5c22d3c3845497210ff7a24e2b8d28c15a6a4..bf9a923e82337ef679193e9049ca097dee830363 100644 (file)
@@ -6,7 +6,7 @@
 // This is compared against the values stored in the database to determine 
 // whether upgrades should be performed (see lib/db/*.php)
 
-   $version = 2005011000;  // YYYYMMDD = date of first major branch release 1.4
+   $version = 2005012500;  // YYYYMMDD = date of first major branch release 1.4
                            //       XY = increments within a single day
 
    $release = '1.5 UNSTABLE DEVELOPMENT';    // Human-friendly version name