See http://moodle.org/mod/forum/discuss.php?d=17269 for description.
}
flush();
+ sync_metacourses();
+
} // End of occasional clean-up tasks
if (file_exists("$CFG->dataroot/cronextra.php")) {
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="" />';
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 ";
+ } ?> <?php print_string("managemetaexplan"); ?>
+ </td>
+</tr>
<tr>
<td></td>
<td><input type="submit" value="<?php print_string("savechanges") ?>" /></td>
$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()) {
" 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);
+}
+
?>
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)) {
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
$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';
$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';
$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';
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
*
}
}
}
+
- 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;
}
?>
`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`),
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');
}
}
+ 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;
}
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);
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');
}
}
+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
*
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;
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 {
$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;
}
// 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