Thursday, September 26, 2013

I built a php page to automate my course DB MySQL scripts...

My customer, my internal customer Shirley handles the formatting of the course page and adds a couple other items to a new course and formats the gradebook items.  I, typically handle the DB side of things.  In other words, I run the scripts that are necessary for each new course that we deploy in our moodle.

I evolved this process from last year by placing all the separate snippets (MySQL snippets), each responsible for a small part of the overall course preparation from the DB standpoint, into a single master SQL snippet.  But, it is still and snippet and only I could run it.

When my customer Shirley keeps asking me to run the DB scripts on the new courses, I start thinking, can I put this script into a HTML/PHP page?  Without putting the DB at risk of hacking?

Always think about whether opening a window, via a form, to your DB is a good idea.  It may not be.  In my case, I decided if I used a select box and a checkbox to handle the interaction with the scripts, that would be ok.

This is what I came up with.  My customer can choose from a select list, a course, and if its a course of type mod, which means setting longer quiz and exam times for students in the course.  By selecting a course and clicking the script it button. php passes the course id to the script, along with a hidden form field value that is used to actually trigger the DB call. This way some hack job who stumbles across the form cant just blindly pass in IDs to the form and have the scripts run.  The course ID is neccessary along with the hidden field value.

Once the script is called, passing along the course ID, I use the moodle DB API function update_records to handle updating the 5 tables necessary to prepare the course.  I also have one insert_record call that I make, inserting the manual enrollment type plugin for the course.

This is what the HTML form looks like






This is the output generated by the PHP, after each script runs.

Now my customer does not have to ask me to run the DB scripts when deploying a new course!  I liked it, so did she.  This is release 1.0.  I am sure there will be requests for updates and changes as the utility gets used more in the wild!






















Technical specs: programming code below.

HTML/PHP

 $recs = getcourses();

echo "h3>Course scripter/h3>";
echo "img src='greencheck.gif'> = script has been runbr>";
echo "img src='redbang.gif'> = script needs to runp>";

echo "form method='post' action='coursePrep.php'>";
// option value="volvo" style="background-image:url(images/volvo.png);">Volvo

    echo "select name='cid'>";
        foreach($recs as $i){
            if($i->isscripted == 1){
                $is = "greencheck.gif";
            }else{
                $is = "redbang.gif";
            }
            if($i->id == $_REQUEST['cid']){
                echo "option value=".$i->id."  style='background-image:url(".$is."); background-repeat:no-repeat; padding-left:30px;' selected> id:".$i->id." ".$i->fullname."option>";
                $_SESSION['fullname'] = $i->fullname;
            }else{
                echo "option value=".$i->id."  style='background-image:url(".$is."); background-repeat:no-repeat; padding-left:30px;'> id:".$i->id." " .$i->fullname."option>";
            }
      
        }
    echo "";
    echo "
    p>/p>
     MOD ? (will set quiz/test time limits to 3,6 hrs)
    br>
    input type='hidden' name='.....'>
    input type='submit' value='Run Script'>form>

";
if(isset($_REQUEST['....'])){

    if(! is_numeric($_REQUEST['cid'])){   
        echo "Invalid courseID";
    }else{
        $cid = $_REQUEST['cid'];
        //var_dump($_REQUEST);
        //var_dump($cid);
        //default ismod is no, if is specified, then set to 1
        $ismod = 0;
        if(isset($_REQUEST['ismod'])){
            $ismod = 1;
        }   
        updateDB($cid,$ismod );
    }
   
}

PHP/SQL scripting:

 function updateDB($cid,$ismod){
    global $DB;
    //echo "
in updateDB....";
    //$DB->update_record($table, $dataObj);
    //echo "ready for sql.....";
    $dataObj = new stdClass();
    $dataObj->id = $cid;
    $dataObj->isscripted = 1;
    $dataObj->maxbytes = 20971520;
    $dataObj->legacyfiles = 2;
    $dataObj->enablecompletion = 1;
    $dataObj->completionstartonenrol = 1;
   
    $table = 'course';
    $DB->update_record($table, $dataObj);
    echo "updated course table is scripted,
max upload = 20 MB,
legacy files are on,
   
enable completion,
completion start on enrol.";
   
    $dataObj = new stdClass();
    $dataObj->id = $cid;
    $dataObj->emailteachers = 1;
    $dataObj->var4 = 1;
    $dataObj->timeavailable = 0;
    $dataObj->timedue = 0;
   
    $table = 'assignment';
    $DB->update_record($table, $dataObj);
   
    echo "updated assessments, emailteachers = 1
submit only once to submit,
always avail at any time.....
";
   
    $dataObj = new stdClass();
    $dataObj->id = $cid;
    $dataObj->decimals = 0;
    $table = 'grade_items';
    $DB->update_record($table, $dataObj);   
            
    echo "updated grade_items, decimals = 0
";
       
    //get modules for the course
    $modules = $DB->get_records_sql('
        SELECT id,course
        FROM mdl_course_modules
        WHERE course = '.$cid.'
    ');
   
    //loop and update module recs
    $cnt=0;
    foreach($modules as $i){
        $dataObj = new stdClass();
        $dataObj->id = $i->id;
        $dataObj->completion = 1;
        $dataObj->completionview = 1;
        $table = 'course_modules';
       
        $DB->update_record($table, $dataObj);//actual update
        $cnt++;
    }
   
    echo "".$cnt." modules updated.
";
   
    echo "updated course modules, completion and completion view = 1
";
   
    $dataObj = new stdClass();
    $dataObj->id = $cid;
    $dataObj->display = 2;// in frame
   
    $table = 'url';
    $DB->update_record($table, $dataObj);   
            
    echo "updated URLS to inframe - 1990 style!
";
   
    $dataObj = new stdClass();
    $dataObj->courseid = $cid;
    $dataObj->enrol = "manual";// in frame                
    $DB->insert_record("enrol", $dataObj);   
   
    echo "Added manual enrollment type...
";
   
    if($ismod){//mod courses require longer times for quiz and exam
        echo "ismod....
";
        $quiztime = 10800;//3 hrs
        $examtime = 21600;//6 hrs
    }else{       
        echo "not mod....
";
        $quiztime = 3600;//1 hr
        $examtime = 7200;//2 hrs
    }
   
    //get quizzes for the course
    $quizzes = $DB->get_records_sql('
        SELECT id,course,name
        FROM mdl_quiz
        WHERE course = '.$cid.'
    ');
   
    //var_dump($quizzes);

    //loop and update quiz recs
    $cnt=0;
    foreach($quizzes as $i){
        $dataObj = new stdClass();
        $dataObj->id = $i->id;
        $table = 'quiz';
       
        if(stristr( $i->name, 'quiz')){
            $dataObj->timelimit = $quiztime;
            //echo "updated Quiz times...
";
        }else{//must be exam or final or test
            $dataObj->timelimit = $examtime;
            //echo "updated Exam times...
";
        }
       
        $DB->update_record($table, $dataObj);//actual update
        $cnt++;
    }
   
    echo "".$cnt." quizzes updated.
";
   
    echo "

Completed scripting for course id ".$cid.",  ".$_SESSION['fullname'] ."

";
   
}
I should also note that I added a field to the course table, isscripted (tinyint()) with a default of 0.  I then updated all the courses isscripted value to 1.  This way, when a new course is added, it defaults correctly to 0, which indicates visually in the interface with a red check mark - indicating that the script should be run on it.

No comments:

Post a Comment