automatic/bulk course creation?

automatic/bulk course creation?

by Barron Koralesky -
Number of replies: 9

While looking at automating enrolment, it seems also important to automate course creation. How have others approached batch/bulk creation of courses for a semester?

Thanks in advance!
Average of ratings: -
In reply to Barron Koralesky

Re: automatic/bulk course creation?

by Scott Krajewski -
I'm looking to try the LDAP enrollment plug-in mentioned here http://moodle.org/mod/forum/discuss.php?d=13333 since it does batch creation from a template which is exactly what we want.  Or else I might look at its guts and see if I can point it towards a database instead of an LDAP server since we don't manage enrollments in our LDAP server.  But I haven't had time! angry
In reply to Barron Koralesky

Re: automatic/bulk course creation?

by denis cahalane -

We have over 3000 courses, so we had to automate. We use sql;  a select statement on the student database pumps out a list of statements of the form:

INSERT into mdl_course VALUES(332,16,0,etc.

In reply to denis cahalane

Re: automatic/bulk course creation?

by Eduardo Monteiro -
Hello Denis,

I am implementing a moodle pilot in a university and would like to know how you have approached bulk course creation.

Would you be so kind and elaborate a little more on your answer?
How are you linking the list of students-courses to the actual course creation?

Thank you in advance,

Eduardo Monteiro
In reply to Eduardo Monteiro

Re: automatic/bulk course creation?

by denis cahalane -

Hi Eduardo. Our student database runs on Oracle, and contains a code and description for every module a student can be registered for. Our aim was to create a moodle course corresponding to each module, and to group them in moodle categories corresponding to departments within the university. The module information is in two tables, so we ran a script like this: (this was last years one theres a few extra fields now in the mdl_course table)

 


spool moodle.in


select 'use moodle;' from dual;


select distinct


 'INSERT into mdl_course VALUES('||ialschooldept||',0,''password'',',


'''2004/2005 '||iahsubj||' '||ialdesc||''',',


'''2005_'||iahsubj||''','''||ialdesc||''',',


'''weeks'',1,'' '',''9,1,11,2,5:7,4,10'',5,''Teacher'',''Teachers'',',


'''Student'',''Students'',0,1096239600,15,0,2097152,',


'0,0,0,'' '',1,0,1087986729,1087986729);'


from stud.iahsub, stud.ialsub


where iahsubj=ialsubj and iahcyr=ialcyr


and iahcyr=2004 and ialschooldept in


(20,21,30,31,32,34,36,40,41,50,56,60,61,62,70,93);


spool off


 


This produced a 12,000 line file that starts off:


use moodle;


INSERT into mdl_course VALUES(20,0,'password',


'2004/2005 59980 Research Subject',


'2005_59980','Research Subject',


'weeks',1,' ','9,1,11,2,5:7,4,10',5,'Teacher','Teachers',


'Student','Students',0,1096239600,15,0,2097152,


0,0,0,' ',1,0,1087986729,1087986729);

 

We passed moodle.in over to the moodle server, and ran it through a perl script that replaced the departmental codes in the student database with the id codes of the moodle categories, and replaced the word password with a random number. I also had the perl script insert id numbers for the table, but I should really have let it autoincrement them itself. Then we ran that against the moodle database, where the categories had already been created.


Im afraid this looks pretty horrible, and the detail will depend on your own setup, but it worked for us. If any more of this might be helpful please ask.

In reply to denis cahalane

Re: automatic/bulk course creation?

by Eduardo Monteiro -
Hi David,

Thanks a lot for the info. It's more or less what I had imagined. The difference is that the data we get from the registration office comes in a flat file.

I am currently working on a solution that does exactly the same thing, but actually using the Moodle API. I want to create a page, or section, that would be accessible from within Moodle and run the bulk course creation.

Right now I'm still deciding what would be best. Getting data from a flat file or by giving database parameters. Maybe I'll do both smile. I'm trying to make it as general as possible so at the end I could share the code, maybe someone out there might use it or improve it.

I have been playing around with a development site and actually found that using the Moodle API is a lot easier than going straight into the database when creating courses. (Thanks again Moodle!)

Well, Thanks again for the info, and I'll make sure I post my success (or failuretongueout) stories, and who knows, maybe the code if I actually get it working.

Thanks,

Edaurdo
In reply to Eduardo Monteiro

Re: automatic/bulk course creation?

by Dallas Ray Smetter -
Eduardo,

I would appreciate you letting me know what you come up with. Our system, Winschool by Chancery Software also outputs a flatfile for me (csv). I am looking to do a mass course export/import this summer for the Fall '05 term.

Peace,
Dallas Ray
In reply to Dallas Ray Smetter

Re: automatic/bulk course creation?

by Eduardo Monteiro -

Hi,

I don't have a solution yet. Our group kinda stalled on this matter, hoping Moodle 1.5 would be out by then. From what I have seen, We will most likely be running 1.4.x for a little while, so we have put this job back in our schedules.

So far I have the code to create a single course without user interaction.

All the fields are being populated manually, so the next step is to put this in a loop and actually populate the fields dynamically. If you are comfortable with PHP, feel free to take this code and work with it.

Good luck!

<?PHP

    require_once("../config.php");
    require_once("lib.php");
    require_once("$CFG->libdir/blocklib.php");
    require_login();
    $id       = (int)optional_param('id', 0);         // course id
    $category = (int)optional_param('category', 0);   // possible default category


            $form->fullname = "COP 9999 - Course";
            $form->shortname = "COP9999";
            $form->summary = "This course was created with no user interaction";
            $form->format = "topics";
            $form->password = "key";
            $form->guest = 0;
            $form->numsections = 5;
            $form->idnumber = '';
            $form->cost = '';
            $form->newsitems = 5;
            $form->showgrades = 1;
            $form->groupmode = 0;
            $form->groupmodeforce = 0;
            $form->category = 3;
            $form->id = "";
            $form->visible = 1;
            $form->teacher = get_string("defaultcourseteacher");
            $form->teachers = get_string("defaultcourseteachers");
            $form->student = get_string("defaultcoursestudent");
            $form->students = get_string("defaultcoursestudents");


print $form;

    $form->startdate = make_timestamp($form->startyear, $form->startmonth, $form->startday);
    $form->timemodified = time();
    $form->timecreated = time();
    $form->blockinfo = blocks_get_default_blocks();

    if ($newcourseid = insert_record("course", $form)) {  // Set up new course
print $newcourseid;

                    $section = NULL;
                    $section->course = $newcourseid;   // Create a default section.
                    $section->section = 0;
                    $section->id = insert_record("course_sections", $section);


                    fix_course_sortorder();
                    add_to_log($newcourseid, "course", "new", "view.php?id=$newcourseid", "");


                        $newteacher = NULL;
                        $newteacher->userid = 3;
                        $newteacher->course = $newcourseid;
                        $newteacher->authority = 1;   // First teacher is the main teacher
                        $newteacher->editall = 1;     // Course creator can edit their own course

                        if (!$newteacher->id = insert_record("user_teachers", $newteacher)) {
                            error("Could not add you to this new course!");
                        }

                        $USER->teacher[$newcourseid] = true;
                        $USER->teacheredit[$newcourseid] = true;
    } else {
        print "ERROR";
    }

?>

In reply to Eduardo Monteiro

Re: automatic/bulk course creation?

by Dallas Ray Smetter -

Comfy indeed. and will be using your code.

Thanks for posting it.

Peace

drs

In reply to Eduardo Monteiro

Re: automatic/bulk course creation?

by Rory Allford -
Hi,

I'm in a similar situation, with a load of course names and descriptions held in a table on another mysql database. I originally started off with a similar approach to Eduardo, using only the built-in moodle functions, basically faking input to the $form object and running it through the remnants of course/edit.php. However this is very slow, and will probably timeout with a reasonable number of records.

I'm no php coder, but I knocked together a script that runs through all the records on one table and makes courses in moodle from them, useful for a direct transfer from an existing database, could easily be adapted for a text file or something. Most of the optimisation is through not using the moodle functions that use ADO and avoiding creating/destroying objects too much. Anyway its a lot faster, averaging about 100 records/sec on our really ancient server running IIS and PHP on debug mode! Hope this can be of use to somebody:

<?php
function microtime_float()
{
    // We don't have php5
    list($usec, $sec) = explode(" ", microtime());
    return ((float)$usec + (float)$sec);
}

function fastcreatecourse($hcategory, $hfullname, $hshortname, $hsummary, $hweeks, $hday, $hmonth, $hyear, $hmtime, $hmaxsize = 2097152) {
    // prevents object pointers being continually created and destroyed, saving time in theory
    static $courseid;
    static $mysqlresource1;
    static $mysqlresource2;
    static $mysqlresource3;
   
    if ($mysqlresource1=mysql_query('SELECT `id` FROM `mdl_course` WHERE `ShortName`=\''.$hshortname.'\'')) { // Check shortname is unique before inserting
        if (mysql_num_rows($mysqlresource1)) {
            return false;
        }
    }

    $mysqlresource2=mysql_query('INSERT INTO `mdl_course` (`category`,`sortorder`,`fullname`,`shortname`,`summary`,`format`,`showgrades`,`newsitems`,`teacher`,`teachers`,`student`,`students`,`startdate`,`numsections`,`maxbytes`,`visible`,`groupmode`,`timecreated`,`timemodified`) VALUES (1, 2000, \''.$hfullname.'\', \''.$hshortname.'\', \''.$hsummary.'\', \'weeks\', 1, 5, \'Teacher\', \'Teachers\', \'Student\', \'Students\','.mktime(0,0,0,$hmonth,$hday,$hyear).','.$hweeks.','.$hmaxsize.',1,1,'.$hmtime.', '.$hmtime.');');
    $courseid=mysql_insert_id();
    $page = page_create_object(PAGE_COURSE_VIEW, $courseid);
    blocks_repopulate_page($page); // Setup blocks
    $mysqlresource3=mysql_query('INSERT INTO `mdl_course_sections` (`course`,`section`) VALUES (\''.$courseid.'\',\'0\');');
    return true;
}
    // Code execution begins here
   
    require_once("config.php"); // Link to moodle libs
    require_once("course/lib.php");
    require_once("$CFG->libdir/blocklib.php");
   
    $mtime=time(); // Initialize some variables
    $n=0;
    $t=0;
    $courseid=-1;
   
    $classes = get_records_sql("SELECT `ClassID`, `ShortName`, `Description` FROM `classrecords`"); // Query our other external database
   
    set_time_limit(300); // Up the php timeout
   
    $time_start = microtime_float(); // Just for timing
   
    foreach ($classes as $class) {    // Iterate through the external databases records
        if (fastcreatecourse(1,$class->ShortName,$class->ShortName,$class->Description,10,1,5,2005, $mtime)) $n++;
        $t++;
    }
   
    $time_end = microtime_float();
   
    echo '<h2>Processed '.$n.' records out of '.$t.'</h2>';
   
    fix_course_sortorder(); // Re-sort courses
   
    echo '<h2>Sorted courses</h2>';
   
    echo '<h2>Total execution time: '.($time_end - $time_start).' secs </h2>';
?>