From a user's perspective, the patch adds an option in the course creation page, "Is this a metacourse? (yes/no) checkbox". If you mark it as a metacourse, the student enrolment page changes. Instead of listing (or offering to search for) students, it lists/searches for courses.
For every course you 'enrol' to the metacourse, all the students in that course are enrolled in the metacourse. Once the metacourse is configured, it works transparently: every time a student enro;ls to (or unenrolls from) a course, she is magically enrolled/unenrolled from the relevant metacourse(s) (although it doesn't happen immediately, may take an hour to show up).
The code prevents nesting of metacourses, to avoid infinite loops.
From the underlying code perspective, we didn't change the enrolment mechanisms -- no extra joins or SQL magic. We added one column to mdl_course to hold the boolean flag of whether it is a metacourse, and we added a table holding the 'course enrolments' that make a metacourse enrolment (it describes a many-to-many relationship between courses).
We have a modified student enrolment page that lists courses, and every time a course is added/removed, it will add/remove the student enrolments to the mdl_user_student table (so the enrolments appear to be "normal" enrolments to the rest of the Moodle code).
After the metacourse is setup, the student enrolments are maintained by moodle's cron.php. We could add logic to enrol_student() and unenrol_student() to make the logic in cron superfluous and the whole thing more scalable and elegant.
We've had this code in production on a large Moodle install where the 'normal' enrolments are coming from an LDAP repository (we are using the LDAP enrolment plugin) and Moodle admins define courses where all the students of (for instance) computer science courses are enrolled. All they do is select the CompSci courses in the metacourse, and it's done; when new enrolments come through the LDAP plugin, they are automatically enrolled in the relevant metacourse.
The code does need a bit of testing in other installs, to make sure we didn't overlook anything, so it'd be great if you can give it a test, and let us know what you think.
Today's patch is brough to you by the letters "NZVLE", in collaboration with Penny Leach, who did the thinking and programming. As usualy, it's experimental, so if it breaks you get to keep all the parts.
The patch applies cleanly to today's CVS HEAD; to apply, unzip the attached file, patch Moodle with meta.diff, place the import_students.php and import_students.html in course and hack your database thus:
- modify your {prefix_}course table saying
(mysql) ALTER TABLE {prefix_}course ADD COLUUMN meta_course INT(1) UNSIGNED NOT NULL DEFAULT '0'
(postgres) ALTER TABLE {prefix_}course ADD COLUUMN meta_course INTEGER NOT NULL DEFAULT '0'
- add the extra table & indexes
(mysql)
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)
);
(postgres)
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);
And finally, in cron.php find the line that updates enrolments:
$enrol->cron();
and add a call to sync_metacourses() right after that.
~ Deleting a course that is either a parent course or a child course needs to have some handling of meta courses implications (ie, pruning enrolments)
~ Changing status between being a meta course or not should be restricted, based on whether there are current enrolments or not (turning a course from a meta course into a normal course shouldn't be allowed if there are 3 child courses and all the enrolments from them, and likewise a course that is not a meta course should not be allowed to be turned into one if there are current enrolments)
~ (bug - thanks Eloy) - turning a meta course into a normal course should ACTUALLY WORK
Thanks, guys.
The other files in the original zip (and .tar.gz) - (new files) importstudents.html and importstudents.php have not changed, only the diff. Just replace the original diff with this one (if you've already applied it, back it out with patch -R).
Hello Penny and Ors,
This feature is truly great.
I need your help to understand and know how to apply the Mtta.diff patch.
Shall be grateful for this help
Garry
Penny
Thanks for the clarification
Garry
I create three metacourses: A, B, C.
I create three courses: 1, 2, 3.
The metacourses consist of the following courses:
A: 1
B: 1, 2
C: 1, 2, 3
Depending on which courses I want a particular student to have access to, I enroll them in either A, B, or C and they are enrolled automatically in the respective courses.
If I am understanding this correctly, then this is absolutely a major advance for me with Moodle and will be very useful for my students.
Think of it like, you have one meta (parent) course called "Languages". Into languages, you assign all the courses that have anything to do with languages. All students enrolled in any of the specialised languages courses will be enrolled into the all encompassing "Languages" parent course.
It was born out of a need for forums that cover many courses, on a faculty or departmental level. So it's bottom up, rather than top down.
With the forum example I was just trying to explain the original rationale behind the development

So you have a 1 to many relationship between the parent and child courses and all enrolled in the various child courses are auto-enrolled in the parent, general course. Interesting. This would be useful.
I could use 1 course for a yeargroup which I could use to enroll all relevant students into and then the enrollments from that one course would feed many other courses. Downward inheritance rather than upward inheritance

Would it be possible to have our cake and eat it?
Something like 2 tick boxes? 1 says this is a metacourse and works the way it works now as you describe. The other says something like this is a child enrollment course and works the way I envisioned it?
- You create one normal course to enroll students.
- All your other courses are meta-courses wich inherit (no sure for the word ) from the first one.
Sorry about that, I am confusing myself now

A Moodler by the name of Rudy Scott was developing a Subsection module a while back. The Metacourse feature sounds similar in some ways to what he was trying to achieve. I thought the code might be helpful in the Metacourse framework of things.
If you have the time, please take a look at:
subsection starting point
http://moodle.org/mod/forum/discuss.php?d=5379
return of the subsection: testing wanted
http://moodle.org/mod/forum/discuss.php?d=10357
Hope you find this helpful.
WP1
This is very useful. Just what I wanted.
The existances of metacourses means that I can have a "help forum" on my front page by linking to a forum in a metacourse that everyone is enrolled in.
I think that it also means that I can have forums that are shared between courses, and only certain courses. If I create a metacourse containing all the members of the several "English Speaking" courses, then I can add a link to a forum in that meta course from all the instances.
Which makes me think, it would be nice to be able to change the icons of activities/resources because, as in this case, sometimes a link is realy a forum.
Tim
I have just had a quick play and am not in a position to test it thouroughly but this means I can now have 1 course for the intake year and then subjects can just 'grab' the enrollments from the parent course

This leads me to my one niggle! I prefer the language in the code of parent and child courses rather than metacourse. Non-techies just wouldn't have a clue what this means although, to be fair, it is explained clearly in the course settings.
Darren

Next year wil be a dream to enroll student !
I agree with Darren for the name which is not really clear...
Can I suggest an other feature more ?
It is an option "with groups" when I choose if the course is a meta-course.
That is, if I choose yes to this option : when students are enrolled in the metacourse, if they belong to a group, this group is created if not exists and the student is put in this group;
If I choose no : the same thing than now
May be there is a problem when several courses with same students but not same groups are enrolled in a meta course. But the rule can be "if a student already exists in a meta course do nothing".
What do you thing about ?
Having groups inherited from the parent course to the child course would be sublime

All of our user management is based around groups so everytime we teach a new unit (around 5 a year for each year group of over 100 students) students have to be enrolled on courses, groups created and then students assigned to groups.
I always anticipated this kind of thing being controlled by the categories but if this course enrollment is looking good for 1.5 then ......





inherithed groups (by name) could be really cool!!
Ciao
But if groups are to be inherited, it causes at least two problems to solve:
- Suppose you have courses A, B, C and D, where D is a metacourse for the others. Courses A and B have groups, course C doesn't. The question is: what should happen to the students from course C? I don't think they should be unassigned, but where should they be assigned to?
- Suppose you have the same courses as in #1, but all the three 'child' courses have groups, but some students are enrolled in more than one. This means that they are in different groups in different courses. When the enrollment is inherited, which group should they be assigned to in the meta course?
There may be more combinations like these.
such type of situations can happen but, if the rules are clear...:
1.- I think they shouldn't be assigned to any group. That's "pure" inheritance.
2.- This is more difficult but the solution should be, "to the last one processed". Not optimal, but computable. It should be consistent (course records processed always in the same order, alphabetically, for example).
That's my 0.5 cents opinion, ciao
Hi Eloy, sorry, it's not that simple
1. It cannot be 'solved' in the child course, because the child course doesn't use groups at all (and the teacher wants it in no-groups mode). And the students who come from the "no-groups" child, if they end up unassigned, will not be able to fully participate in the metacourse activities.
2. Doesn't matter what solution is adopted (alphabetical, course id, or whatever), it still is almost identical to random assignment.
For the time being, I think it's better to hold the group inheritance back for a while and implement it only when we can think of some other solutions.
Another idea for #1: when a metacourse is created, a special group is automatically created (it could be called "unassigned" for example) in it and all
a/ unassigned students from courses with groups and
b/ students from courses without groups
become assigned to this group.
Still no ideas for #2.
Martin, Penny, Eloy, et. al., what do you think?
your #1 alternative sounds better than mine! Sure! But I only create the "unassigned" group if some of the child courses have users in groups!
about #2, the order can be the order specified in the enrolment page, records will be processed in such order and the first will have preference. Not totally clear, but at least it's a potential rule to follow... It will imply to add an "up/down" control to such page, but it seems possible, isn't it?
Ciao
This is a nice feature, although in large organizations, where all people is already registered in a database, can be accomplished by rules to enroll people from the database.
I think the true revolutionary idea is the one placed by Etienne: inheritance.
He asked inheritance of groups. I am now dreaming with inheritance of calendar events. At ULPGC we are now facing end-term exams. I would love to be able to see, as a teacher, the dates my Biochemistry students are having exams of other disciplines, just to coordinate the calendar. They do see possible conflicts in their calendars, but teachers are not enrolled in other disciplines.
Now it is impossible to do that with calendar. We have course or site events. Site events are not suited for this at a University with >1000 simultaneous courses: the calendar would be a mess. But if we can setup a metacourse for "first year medical students" "second year Topography" or "Third year History", there would be a place to share this calendar for students and teacher. And perhaps, inheritance can be extended to other features!.
What do you think?
- Enrique -
I have a addon for moodle that lets teachers see at a glance when their students have tests in other subjects. It's a script that does a series of selects to pick out all tests that touch your students. The teacher gets this view: (the blue frame is popup info showing the student that has a test with teacher niwi).


This is a very good idea. I am going to ask our IT people to try to develop a custom blok for this.
- Enrique -

In my local moodle I have timetable data for each teacher/student. Thus the script can check to see that the test is placed correctly. A test placed outside the times given by the timetable get marked with red, but are accepted into the db (the teach is assumed to know what he/she is doing). Also generall events that preclude a test (excursions etc) are marked in the test-planner, blocking tests for that day.
I'm working on making a custom block for timetable data and room-reservations. The block for test-planning could perhaps integrate with this.
It's great to hear that you are working on a scheduling block. We've been using phpSchedulIt ( http://sourceforge.net/projects/phpscheduleit/ ) but we would love to see something added to Moodle.
I find this feature quite useful for what we want, but I need it to work with the latest stable version (1.4.3) and I'd like to know if someone has succeed in getting it working with that version.
I applied metav2.diff patch and two files rejects to be patched ("blocks/admin/blocks_admin.php" and "lib/moodlelib.php"), any suggestions?
Thanks in advance.
Regards,
Jose Manuel.
-------------------------------------------------------------
Metacourses. Well, we're *running* it against 1.4, for Open Poly, but I don't have a single patch really. Our arch repo is publicly accessible, though. Are you familiar with arch? It's quite different from cvs.
Anyway, you can browse it at
http://lists.eduforge.org/cgi-bin/archzoom.cgi
( you want moodle--eduforge--1.3.3 ).
Which is kind of a pain really. The two *new* files can be easily got though from there - course/importstudents.(html|php) - just make sure you get it from the latest patchset though.
Or, you can actually use arch to get it, which will probably result in some steep learning curve
Probably the best thing to do is download the files you need from archzoom and diff them against 1.4 clean. There may be some non metacourse related stuff in there but it should be reasonably obvious which hunks you need.
So, the latest patchset seems to be 495, so you want to go to
http://lists.eduforge.org/cgi-bin/archzoom.cgi/arch-eduforge@catalyst.net.nz--2004/moodle--eduforge--1.3.3--patch-495
The files you need are:
course/importstudents.html
course/importstudents.php
blocks/admin/block_admin.php
course/edit.html
course/edit.php
course/student.php
lang/en/moodle.php
course/lib.php
lib/datalib.php
lib/moodlelib.php
lib/db/*
The * on the left is the download for each file.
It might be worth taking a look at the lib/db/* files and make the tables manually because they went through like 3 iterations before it was right :o
Basically, you just need one table, course_meta and a new field in course, metacourse. But it's far less complicated to set it up from scratch with the version numbers and the many iterations.
--------------------------------------------------------
But, then afterwards I remembered something else and also wrote this:
----------------------------------------------------------
oh! I forgot to say, also, that Eloy has done some work with
backup/restore for metacourses that I don't really know about. You may
want to backport those patches from HEAD.
-----------------------------------------------------------
Hope that helps. By the way, 495 is no longer the latest patch, so if you want to do it this way, you'll need 518.
Good luck!
I would like to create different access level in Moodle.
You can image a university with different faculties, in which there are many departiments and many courses for each departiment. Maybe that people of a particular departiment is not interested in courses of other faculties.
Otherwise you can image an e-learning content provider that want a client see only its courses and not courses of other clients.
Is someone interested in developing meta courses so that, when you login you start directly from your specific metacourse and you can see only courses that are under that meta course?
Fair
Hi,
Initially, I created a subject (or course) and in Settings clicked No - not a meta course. Now, however, the lecturer wants to give access to another class, making it a meta course. When I go in to change the settings to Yes - it is a meta course, I'm unable to do so because the option is not available. Is there anyway to sort this out other than starting over and recreating the subject?
Thanks,
Sue
Hi Sue,
you will need to unenrol the existing students first - go to the students page and remove all students enrolled in the course - then you should be able to turn it into a meta-course.
Dan
Hi Dan,
Thanks Dan, but that doesn't seem to work. I've taken all the student (3 so far) plus the subject code away but it still doesn't give me the option to make it a meta course. I've created a new subject (340a) and have copied the material across and will redo the links. My worry, is that once Axel checks it and I delete the original subject, will I be able to rename the new one to the old name?
Sue
Hi Sue,
there were 2 problems:
1 - there was still one student registered in the course you wanted to turn into a Meta-Course (this may have happened just after you removed everyone - or it has happened after you tried to change it)
2 - the course was a member of another meta-course.
- a meta-course can't be part of another meta-course, they can only be 1-deep.
should be fine now!
Dan
Hello
O think this feature could be very intersting. The same idea about offer a metacourse for a department or a subject we could use for different organizations or groups that are using a same server of Moode. My specific case is that we offer Moodle for different NGOs and each one has several courses or communities. If I could have the option to specify a metacourse of a group of courses would be fantastic. Example:
I have a NGO that works with health issues and offer some courses or collaborative spaces in such subject. That NGO could creactes a Metacourse that would be the "homepage"of these courses or the "portal" of his communities.
If I have this option I could create a metacourse for each NGO or department and automatically create a space for information sharing and comunication among people with similar interests.
I think that feature should be easy to be deveoped, dont is?
Best wishes
dalberto
Hello
I just discovered that this idea is already possible. I just need create a metacourse and after select only the courses that I would like to "subscribe" to that metacourse.
Fantastic.
Beste wishes
dalberto
i'm hoping this is the right place for this post. we have created a meta course "A" that has reusable topics and is thus used by two other courses "B" & "C". "B" & "C" are enrolled in meta course "A." participants in "B" and "C" can access meta course "A" but not teachers. this is a real problem for us and i would expect for others as well for obvious reasons.
can someone please provide some insight how we can fix this?
thx!
just an average moodler trying to change the universe
We have a meta-course with two sub-courses enrolled in it. We have 120 student enrolled per sub-course and they're been able to use the meta-course without any problems except in this one case. A student unenrolled from one of the sub-courses and enrolled into the other. Now the student can not access the meta-course any longer.
I've looked at three tables (mdl_user, mdl_user_students, and mdl_course_meta) and can see the key relationships are in order. mdl_course_meta.parent_course is set to 16 which is the correct id for the meta-course, and mdl_course_meta.child_course is set to 30 which is the correct sub-course in which the student last enrolled. This value also correctly matches the value at mdl_user_students.course for the student's record. (I include a dump of the pertinent records from these three tables below.)
We're running Moodle 1.5.3+ (2005060230) and using LDAP authentication and a MySQL enrolment table.
Could the time fields play a role in the problem? Any advice is appreciated.
Jose
<!-- Table mdl_user -->
<mdl_user>
<id>433</id>
<auth>ldap</auth>
<confirmed>1</confirmed>
<policyagreed>0</policyagreed>
<deleted>0</deleted>
<username>XXXXXXX</username>
<password>not cached</password>
<idnumber></idnumber>
<firstname>XXXXXXXXX</firstname>
<lastname>XXXXXXXXX</lastname>
<email>XXXXXXXX</email>
<emailstop>0</emailstop>
<skype></skype>
<yahoo></yahoo>
<aim></aim>
<msn></msn>
<city></city>
<lang>en</lang>
<theme></theme>
<timezone>99</timezone>
<firstaccess>0</firstaccess>
<lastaccess>1138393494</lastaccess>
<lastlogin>1138318340</lastlogin>
<currentlogin>1138393086</currentlogin>
<lastIP>XXXXXXXXXX</lastIP>
<mailformat>1</mailformat>
<maildigest>0</maildigest>
<maildisplay>2</maildisplay>
<htmleditor>1</htmleditor>
<autosubscribe>1</autosubscribe>
<trackforums>0</trackforums>
<timemodified>1136777558</timemodified>
</mdl_user>
<!-- Table mdl_user_students -->
<mdl_user_students>
<id>1343</id>
<userid>433</userid>
<course>30</course>
<timestart>0</timestart>
<timeend>0</timeend>
<time>1138061604</time>
<timeaccess>1138393229</timeaccess>
<enrol>database</enrol>
</mdl_user_students>
<!-- Table mdl_course_meta -->
<mdl_course_meta>
<id>4</id>
<parent_course>16</parent_course>
<child_course>30</child_course>
</mdl_course_meta>
I fixed a bug in metacourses a few weeks ago, can you upgrade to the LATEST 1.5.3+ and let me know if that fixes the problem?
- Penny
The process revealed what should have been obvious to me (had I studied the records of the other students more closely), two records in the mdl_student_user table should exist per metacourse enrollee, one tagged 'enroll' and the other tagged 'metacourse'. For some reason the 'metacourse' record was missing the first time the student logged in. Luckily the second attempt at logging in fixed it.
I will apply your patches for good measure. Without knowing how the code handles record contention, I can imagine how a student logging in just as the enrolment table is being updated could cause this problem. It seems like a rare problem.
Thank you,
Jose
<!-- Table mdl_user_students -->
<mdl_user_students>
<id>1369</id>
<userid>433</userid>
<course>16</course>
<timestart>0</timestart>
<timeend>0</timeend>
<time>1138410688</time>
<timeaccess>1138410695</timeaccess>
<enrol>metacourse</enrol>
</mdl_user_students>
<mdl_user_students>
<id>1370</id>
<userid>433</userid>
<course>30</course>
<timestart>0</timestart>
<timeend>0</timeend>
<time>1138410688</time>
<timeaccess>0</timeaccess>
<enrol>database</enrol>
</mdl_user_students>
0=?
1=?
2=?
etc
Which is Text Only emails
Which is html email