]> git.mjollnir.org Git - moodle.git/commitdiff
Added new import format - Course Test Manager - from Russell Jungwirth.
authormoodler <moodler>
Wed, 15 Oct 2003 08:53:51 +0000 (08:53 +0000)
committermoodler <moodler>
Wed, 15 Oct 2003 08:53:51 +0000 (08:53 +0000)
All I've done is clean up the source code - I've not tested it at all.

mod/quiz/format/coursetestmanager.php [new file with mode: 0755]
mod/quiz/import.php
mod/quiz/lib.php

diff --git a/mod/quiz/format/coursetestmanager.php b/mod/quiz/format/coursetestmanager.php
new file mode 100755 (executable)
index 0000000..395649c
--- /dev/null
@@ -0,0 +1,506 @@
+<?PHP  // $Id$ 
+////////////////////////////////////////////////////////////////////
+/// Class for importing course test manager questions.            //
+///                                                               //
+/// Russell Jungwirth                                             // 
+////////////////////////////////////////////////////////////////////
+// Included by ../import.php
+
+
+class quiz_file_format {
+    function importpreprocess($category) {
+        $this->category = $category;  // Important
+        return true;
+    }
+    function importprocess($filename) {
+        global $CFG,$QUIZ_FILE_FORMAT,$strimportquestions,$form,$question_category,$category,$course,$THEME,
+        $hostname, $mdapath, $mdbpath;
+        if ((PHP_OS == "Linux") and isset($hostname)) {
+            $hostname = trim($hostname);
+            // test the ODBC socket server connection
+            // if failure, unset hostname and set hostname_access_error
+            $question_categories = $this->getquestioncategories($mdbpath, $mdapath, $hostname);
+            if (!$question_categories) { 
+                $hostname_access_error = $hostname . " ";
+                unset($hostname);
+            } else  {
+                $hostname_access_error = 0;
+            }
+        }
+
+        if ((PHP_OS == "Linux") and !isset($hostname)) {
+            // copy the file to a semi-permanent location
+            if (! $basedir = make_upload_directory("$course->id")) {
+                error("The site administrator needs to fix the file permissions for the data directory");
+            }
+            if (!isset($hostname_access_error)) { 
+                $bname=basename($filename);
+                $cleanfilename = clean_filename($bname);
+                if ($cleanfilename) {
+                    $newfile = "$basedir/$cleanfilename";
+                    if (move_uploaded_file($filename, $newfile)) {
+                        chmod($newfile, 0666);
+                    } else {
+                        notify(get_string("uploadproblem", "", $filename));
+                    }
+                }
+                $filename = $newfile;
+            }
+            print_heading_with_help($strimportquestions, "import", "quiz");
+            print_simple_box_start("center", "", "$THEME->cellheading");
+            if ($hostname_access_error) { notify("couldn't connect to ODBC Socket Server on " . $hostname_access_error); }
+            echo "<form method=\"post\" action=\"import.php\">";
+            echo "<table cellpadding=5>";
+
+            echo "<tr><td align=right>";
+            echo "What is the hostname or IP address of the ODBC Socket Server:</td><td>";
+            echo " <input name=\"hostname\" type=\"text\" size=\"50\" value=\"".stripslashes($hostname_access_error)."\">";
+            echo " <input name=\"filename\" type=\"hidden\" value=\"".$filename."\">";
+            echo " <input name=\"category\" type=\"hidden\" value=\"".$category->id."\">";
+            echo " <input name=\"format\" type=\"hidden\" value=\"".$form->format."\">";
+            echo "</td><td>&nbsp;</td></tr>";
+            echo "<tr><td align=right>";
+            echo "What is the location of the database (.mdb file) on the Socket Server:</td><td>";
+            echo " <input name=\"mdbpath\" type=\"text\" size=\"50\" value=\"".stripslashes($mdbpath)."\">";
+            echo "</td><td>&nbsp;</td></tr>";
+            echo "<tr><td align=right>";
+            echo "What is the location of the system database (System.mda file) on the Socket Server:</td><td>";
+            echo " <input name=\"mdapath\" type=\"text\" size=\"50\" value=\"".stripslashes($mdapath)."\">";
+            echo "</td><td>&nbsp;</td></tr>";
+            echo "<tr><td>&nbsp;</td><td>";
+            echo " <input type=submit name=save value=\"Connect to Server\">";
+            echo "</td></tr>";
+            echo "</table>";
+            echo "</form>";
+            print_simple_box_end();
+            print_footer($course);
+            exit;
+        } 
+
+        // we get here if running windows or after connect to ODBC socket server on linux
+        //
+        // this generates the page to choose categories of questions to import
+        //
+        if (!isset($question_category)) {
+
+            if (PHP_OS == "WINNT") { 
+                // copy the file to a semi-permanent location
+                if (! $basedir = make_upload_directory("$course->id")) {
+                    error("The site administrator needs to fix the file permissions for the data directory");
+                }
+                $bname=basename($filename);
+                $cleanfilename = clean_filename($bname);
+                if ($cleanfilename) {
+                    $newfile = "$basedir/$cleanfilename";
+                    if (move_uploaded_file($filename, $newfile)) {
+                        chmod($newfile, 0666);
+                    } else {
+                        notify(get_string("uploadproblem", "", $filename));
+                    }
+                }
+                $filename = $newfile;
+            }
+            // end of file copy
+
+            // don't have to do this on linux, since it's alreay been done in the test above
+            if (PHP_OS == "WINNT") { $question_categories = $this->getquestioncategories($filename); }
+            // print the intermediary form
+            if (!$categories = quiz_get_category_menu($course->id, true)) {
+                error("No categories!");
+            }
+            print_heading_with_help($strimportquestions, "import", "quiz");
+            print_simple_box_start("center", "", "$THEME->cellheading");
+            echo "<form method=\"post\" action=\"import.php\">";
+            echo "<table cellpadding=5>";
+            echo "<tr><td align=right>";
+            echo "Choose a category of questions to import:</td><td>";
+            asort($question_categories);
+            choose_from_menu($question_categories, "question_category","All Categories","All Categories", "", "allcategories");
+            echo " <input name=\"filename\" type=\"hidden\" value=\"".$filename."\">";
+            echo " <input name=\"category\" type=\"hidden\" value=\"".$category->id."\">";
+            echo " <input name=\"format\" type=\"hidden\" value=\"".$form->format."\">";
+            if (PHP_OS == "Linux") {
+                echo " <input name=\"hostname\" type=\"hidden\" value=\"".stripslashes(trim($hostname))."\">";
+                echo " <input name=\"mdbpath\" type=\"hidden\" value=\"".stripslashes($mdbpath)."\">";
+                echo " <input name=\"mdapath\" type=\"hidden\" value=\"".stripslashes($mdapath)."\">";
+            }
+            echo "</td><td>&nbsp;</td>";
+            echo "</tr><tr><td>&nbsp;</td><td>";
+            echo " <input type=submit name=save value=\"Import Questions\">";
+            echo "</td></tr>";
+            echo "</table>";
+            echo "</form>";
+            print_simple_box_end();
+            print_footer($course);
+            exit;
+        }
+        //
+        // this is the main import section
+        //
+        notify("Importing questions");
+        if (PHP_OS == "Linux") { 
+            $hostname = trim($hostname);
+            $records = $this->getquestions($mdbpath,$question_category,$mdapath, $hostname);
+        } else {
+            $records = $this->getquestions($filename,$question_category);
+        }
+        foreach ($records as $qrec)
+        {
+            $question = NULL;
+            $question->image = "";     // No images with this format
+            if ($qrec[9] != "") {
+                $question->image = $qrec[9];
+            }
+            $question->defaultgrade = 1;
+            // 0       Selected
+            // 1       PracticeTestOK?
+            // 2       QuestionText
+            // 3       QuestionType
+            // 4       Option1Text
+            // 5       Option2Text
+            // 6       Option3Text
+            // 7       Option4Text
+            // 8       CorrectAnswer
+            // 9       Graphic
+            // 10      Module
+            // 11      ChapterNumber
+            // 12      PageNumber
+            $ref = "Answer can be found in chapter ". $qrec[11] . ", page " . $qrec[12] . ".";
+            switch ($qrec[3]) {
+                case 1:                                
+                    $question->qtype = MULTICHOICE; // MULTICHOICE, SHORTANSWER, TRUEFALSE
+                    //                 echo "<pre>";echo htmlspecialchars($qrec[2]); echo "</pre>";
+                    $question->questiontext = addslashes(trim($qrec[2]));
+                    //                 echo "<pre>";echo $question->questiontext; echo "</pre>";
+                    $question->name = preg_replace("/<br>/", "", $question->questiontext);
+                    $question->single = 1;     // Only one answer is allowed -- used for multiple choicers
+                    $fractionset = 0;
+                    for ($i=4;$i<=7;$i++) {
+                        if ($qrec[$i] != "") {
+                            $question->answer[$i-3]=addslashes($qrec[$i]);
+                            if ($qrec[8] == $i-3) {  // if this is the index of CorrectAnswer
+                                $question->fraction[$i-3] = 1;
+                                $fractionset = 1;
+                            } else {
+                                $question->fraction[$i-3] = 0;
+                            }
+                            $question->feedback[$i-3] = (($qrec[8] == $i-3)?"Correct. ":"Incorrect. ") . $ref;
+                        }
+                    }
+                    if ($fractionset == 0) { $question->fraction[1] = 1; }
+                    break;
+                case 2:  // TRUE FALSE
+                    $question->qtype = TRUEFALSE; 
+                    $question->questiontext = addslashes(trim($qrec[2]));
+                    $question->name = preg_replace("/<br>/", "", $question->questiontext);
+                    // for TF, $question->answer should be 1 for true, 0 for false
+                    if ($qrec[8] == "T") { $question->answer =1; echo "answer T"; } else { $question->answer = 0; }
+                    // for TF, use $question->feedbacktrue and feedbackfalse
+                    $question->feedbacktrue = (($qrec[8] =="T")?"Correct. ":"Incorrect. ") . $ref;
+                    $question->feedbackfalse = (($qrec[8] =="F")?"Correct. ":"Incorrect. ") . $ref;
+                    break;
+                case 3:
+                    $question->qtype = SHORTANSWER;
+                    $question->questiontext = addslashes(trim($qrec[2]));
+                    //                 echo "<pre>";echo $question->questiontext; echo "</pre>";
+                    $question->name = preg_replace("/<br>/", "", $question->questiontext);
+                    $question->usecase=0;  // Ignore case -- for SHORT ANSWER questions
+                    $answers = explode("~", $qrec[8]);
+                    $question->answer[1]=" ";
+                    $question->fraction[1]=1;
+                    for ($i=0;$i<count($answers);$i++) {
+                        $question->answer[$i] = addslashes(trim($answers[$i]));
+                        $question->feedback[$i] = $ref;
+                        $question->fraction[$i] = 1; // 1 for 100%, 0 for none or somewhere in between
+                    }
+                    break;
+                case 4:
+                    $question = 0;
+                    notify("Cannot use essay questions - skipping question ". $qrec[2] . " " . $ref);
+                    break;
+                default:
+                    $question = 0;
+                    notify("Misformatted Record.  Question Skipped.");
+                    break;
+            }
+            if ($question) { $questions[] = $question; }
+        }
+        $count = 0;
+        // process all the questions
+        if (PHP_OS == "WINNT") {
+            $filename = str_replace("\\\\","\\",$filename);
+            $filename = str_replace("/","\\",$filename);
+        }
+        foreach ($questions as $question) {   // Process and store each question
+            $count++;
+            echo "<hr><p><b>$count</b>. ".stripslashes($question->questiontext)."</p>";
+            $question->category = $this->category->id;
+            $question->stamp = make_unique_id_code();  // Set the unique code (not to be changed)
+            $question->version = 1;                    // Original version of this question
+            if (!$question->id = insert_record("quiz_questions", $question)) {
+                error("Could not insert new question!");
+            }
+            $this->questionids[] = $question->id;
+            // Now to save all the answers and type-specific options
+            $result = quiz_save_question_options($question);
+            if (!empty($result->error)) {
+                notify($result->error);
+                $this->deletedatabase($filename);
+                return false;
+            }
+            if (!empty($result->notice)) {
+                notify($result->notice);
+                $this->deletedatabase($filename);
+                return true;
+            }
+        }
+        $this->deletedatabase($filename);
+        return true;
+    }
+
+    function importpostprocess() {
+        return true;
+    }
+
+    function deletedatabase($filename) {
+        if (! $this->fulldelete($filename)) {
+            echo "<BR>Error: Could not delete: $filename";
+            return false;
+        }
+        return true;
+    }
+
+    function getquestions($filename, $category, $mdapath="", $hostname="") {
+        if (($category == "allcategories") or ($category == "")) {
+            $sql = "SELECT * FROM TBQuestions";
+        } else {
+            $sql = "SELECT * FROM TBQuestions where module = '".$category."'";
+        }
+        if (PHP_OS == "WINNT") {
+            $ldb =& $this->connect_win($filename);
+            $qset = $ldb->Execute("$sql");
+            if ( $qset->RecordCount() > 0 ) {
+                $records = $qset->GetAssoc(true);
+            } else {
+                $this->err("There were no records in the database.",$dsn);
+                $ldb->Close();
+                return false;
+            }
+            $ldb->Close();
+        } else  { // if PHP_OS == WINNT
+            // we have a linux installation
+            $result = $this->query_linux($sql,$filename, $mdapath,$hostname);
+            if ( count($result) > 0 ) {
+                // get rid of the ID field in the first column.
+                for($i=0;$i<count($result);$i++) {
+                    foreach (array_keys($result[$i]) as $j) {
+                        $records[$i][$j-1] = $result[$i][$j];
+                    }
+                }
+            } else {
+                $this->err("There were no records in the database.",$dsn);
+                $ldb->Close();
+                return false;
+            }
+            // xml test and connect
+        }  // PHP_OS TEST
+        return $records;
+    }
+
+    function getquestioncategories($filename, $mdapath="", $hostname="") {
+        global $CFG, $result;
+        $sql = "SELECT Distinct module FROM TBQuestions";
+        if (PHP_OS == "WINNT") {
+            $ldb =& $this->connect_win($filename);                             
+            $qset = $ldb->Execute("$sql");
+            if ( $qset->RecordCount() > 0 ) {
+                $records = $qset->GetArray(true);
+                foreach ($records as $record) {
+                    $categories[$record[0]] = $record[0];
+                }
+            } else { // if recordcount 
+                $this->err("There were no records in the database.",$dsn);
+                $ldb->Close();
+                return false;
+            }
+            $ldb->Close();
+        } else  { // if PHP_OS == WINNT
+            // we have a linux installation
+            $result = $this->query_linux($sql, $filename, $mdapath, $hostname);
+            for($i=0;$i<count($result);$i++) {
+                $categories[$result[$i][0]] = $result[$i][0];
+            }
+        }  // PHP_OS TEST
+        return $categories;
+    }
+
+    function query_linux($sql, $mdbpath, $mdapath, $hostname) {
+        global $result;
+        include_once("$CFG->libdir/odbc.php");
+        // set up socket server object to connect to remote host
+        $oTest = new ODBCSocketServer;
+        //Set the Hostname, port, and connection string
+        $oTest->sHostName = $hostname;
+        $oTest->nPort = 9628;
+        //                       $oTest->sConnectionString="DRIVER=Microsoft Access Driver (*.mdb);SystemDB=C:\CTM\System.mda;DBQ=C:\CTM\of2K3\ctm.mdb;UID=Assess;PWD=VBMango;";
+        $oTest->sConnectionString="DRIVER=Microsoft Access Driver (*.mdb);SystemDB=".
+            $mdapath.";DBQ=".$mdbpath.";UID=Assess;PWD=VBMango;";
+        // send and receive XML communication
+        $qResult = $oTest->ExecSQL($sql);
+        // set up XML parser to read the results
+        $xml_parser = xml_parser_create("US-ASCII");
+        xml_set_element_handler($xml_parser, "quiz_xmlstart", "quiz_xmlend");
+        xml_set_character_data_handler($xml_parser, "quiz_xmldata");
+        // parse the XML and get back the result set array
+        if (!xml_parse($xml_parser, $qResult)) {
+            $this->err("XML error: ".xml_error_string(xml_get_error_code($xml_parser))
+                    ." at line ".xml_get_current_line_number($xml_parser),$oTest->sConnectionString);
+            return false;
+        } else  { 
+            //         echo("Successful XML parse.  ");
+            // prepare the array for use in the pull-down
+            /*         echo "<br>count of rows is ". count ($result);
+                        echo "<pre>\n";
+                        $qResult = HtmlSpecialChars($qResult);
+                        echo $qResult;
+                        echo "\n</pre>";
+             */
+            xml_parser_free($xml_parser);
+            // $sResult = HtmlSpecialChars($qResult);
+            //echo("<pre>");
+            // echo($sResult);
+            // echo("</pre>");
+
+            return $result;
+        }
+    } 
+
+    function connect_win($filename) {
+        global $CFG, $systemdb;
+        // first, verify the location of System.mda
+        if (!isset($systemdb)) { 
+            $systemdb=$this->findfile("System.mda");
+        }
+        if (! $systemdb) {
+            $this->err("The system database System.mda cannot be found.  Check that you've uploaded it to the course.",$dsn);
+            die;
+        }
+
+        $ldb = &ADONewConnection('access');
+        $dsn="DRIVER=Microsoft Access Driver (*.mdb);SystemDB=".$systemdb.";DBQ=".$filename.";UID=Assess;PWD=VBMango;";
+        $dbconnected = $ldb->Connect($dsn);
+        if (! $dbconnected) {
+            $this->err("Moodle could not connect to the database.",$dsn);
+            die;
+        }
+        return $ldb;
+    }
+
+    function err($message, $dsn) {
+        echo "<font color=\"#990000\">";
+        echo "<p>Error: $message</p>";
+        echo "<p>ODBC File DSN: $dsn<br />";
+        echo "</font>";
+    }          
+
+    function fulldelete($location) { 
+        if (is_dir($location)) {
+            $currdir = opendir($location);
+            while ($file = readdir($currdir)) { 
+                if ($file <> ".." && $file <> ".") {
+                    $fullfile = $location."/".$file;
+                    if (is_dir($fullfile)) { 
+                        if (!fulldelete($fullfile)) {
+                            return false;
+                        }
+                    } else {
+                        if (!unlink($fullfile)) {
+                            return false;
+                        }
+                    } 
+                }
+            } 
+            closedir($currdir);
+            if (! rmdir($location)) {
+                return false;
+            }
+
+        } else {
+            if (!unlink($location)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    function findfile($filename) { 
+        global $CFG;
+        $dirs = $this->getcoursedirs();
+        $dirs[] = $CFG->dirroot."\mod\quiz\format";
+        foreach ($dirs as $dir) {
+            $file = $dir . "\System.mda";
+            // look for System.mda
+            if (is_file($file)) return $file;
+        }                      
+        return false;
+    }
+
+    function getcoursedirs() {
+        global $CFG;
+        // for every course in the system, find the root of the data directory
+        $courses = get_records_sql("select distinct id,fullname from ".$CFG->prefix."course");
+        $dirs = array();
+        if ($courses) {
+            foreach ($courses as $course) {
+                $dir = $CFG->dataroot . "/" . $course->id;
+                if (is_dir($dir)) { $dirs[] = $dir; }
+            }
+        }
+        return $dirs;
+    }
+
+} // END OF CLASS
+
+//Handler for starting elements
+function quiz_xmlstart($parser, $name, $attribs) { 
+    global $result,$row, $col, $incolumn;
+    $name = strtolower($name);
+    switch ($name) {
+        case "row":
+            $col=0;break;
+        case "column":
+            $incolumn = 1;break;
+        case "error":
+            break;
+        case "result":
+            $row = 0; break;
+    } // switch
+}
+
+//handler for the end of elements
+function quiz_xmlend($parser, $name) {
+    global $result, $row, $col, $incolumn;
+    $name = strtolower($name);
+    switch ($name) {
+        case "row":
+            $row++;break;
+        case "column":
+            $incolumn = 0;
+        $col++;
+        break;
+        case "error":
+            break;
+        case "result":
+            break;
+    } // switch
+}  // function
+
+//handler for character data
+function quiz_xmldata($parser, $data) {
+    global $result, $row, $col, $incolumn;
+    if ($incolumn) { $result[$row][$col] = $result[$row][$col] . $data;
+    }
+}
+
+?>
index a723156b86bf209fe0c13d88bc78c2a3751658a6..ee7f77b329a04be937517d74a95e3ca412339a5f 100644 (file)
 
     if ($form = data_submitted()) {   /// Filename
 
-        if (!empty($_FILES['newfile'])) {
+        if (isset($form->filename)) {                 // file already on server
+            $newfile['tmp_name'] = $form->filename; 
+            $newfile['size'] = filesize($form->filename);
+
+        } else if (!empty($_FILES['newfile'])) {      // file was just uploaded
             $newfile = $_FILES['newfile'];
         }
 
         if (empty($newfile)) {
             notify(get_string("uploadproblem") );
 
-        } else if (!is_uploaded_file($newfile['tmp_name']) or $newfile['size'] == 0) {
+        } else if (!isset($filename) and (!is_uploaded_file($newfile['tmp_name']) or $newfile['size'] == 0)) {
             notify(get_string("uploadnofilefound") );
 
-        } else {
+        } else {  // Valid file is found
 
             if (! is_readable("format/$form->format".".php")) {
                 error("Format not known ($form->format)");
index d4765f0413f77f955c40bccfc9095d36f2d6a6c7..7605b3b1def7c6e28535d8c766d84db3eca039bf 100644 (file)
@@ -38,7 +38,8 @@ $QUIZ_FILE_FORMAT = array ( "custom"   => get_string("custom", "quiz"),
                             "missingword" => get_string("missingword", "quiz"),
                             "blackboard" => get_string("blackboard", "quiz"),
                             "aon" => "AON",
-                            "multianswer" => get_string("multianswer", "quiz")
+                            "multianswer" => get_string("multianswer", "quiz"),
+                            "coursetestmanager" => "Course Test Manager"
                             );
 
 define("QUIZ_PICTURE_MAX_HEIGHT", "600");   // Not currently implemented