From: moodler Date: Wed, 15 Oct 2003 08:53:51 +0000 (+0000) Subject: Added new import format - Course Test Manager - from Russell Jungwirth. X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=857e0dfdd5ee3501eea54178829c094784bbd1f2;p=moodle.git Added new import format - Course Test Manager - from Russell Jungwirth. All I've done is clean up the source code - I've not tested it at all. --- diff --git a/mod/quiz/format/coursetestmanager.php b/mod/quiz/format/coursetestmanager.php new file mode 100755 index 0000000000..395649c8c8 --- /dev/null +++ b/mod/quiz/format/coursetestmanager.php @@ -0,0 +1,506 @@ +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 "
"; + echo ""; + + echo ""; + echo ""; + echo ""; + echo ""; + echo "
"; + echo "What is the hostname or IP address of the ODBC Socket Server:"; + echo " "; + echo " "; + echo " id."\">"; + echo " format."\">"; + echo " 
"; + echo "What is the location of the database (.mdb file) on the Socket Server:"; + echo " "; + echo " 
"; + echo "What is the location of the system database (System.mda file) on the Socket Server:"; + echo " "; + echo " 
 "; + echo " "; + echo "
"; + echo "
"; + 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 "
"; + echo ""; + echo ""; + echo ""; + echo "
"; + echo "Choose a category of questions to import:"; + asort($question_categories); + choose_from_menu($question_categories, "question_category","All Categories","All Categories", "", "allcategories"); + echo " "; + echo " id."\">"; + echo " format."\">"; + if (PHP_OS == "Linux") { + echo " "; + echo " "; + echo " "; + } + echo " 
 "; + echo " "; + echo "
"; + echo "
"; + 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 "
";echo htmlspecialchars($qrec[2]); echo "
"; + $question->questiontext = addslashes(trim($qrec[2])); + // echo "
";echo $question->questiontext; echo "
"; + $question->name = preg_replace("/
/", "", $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("/
/", "", $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 "
";echo $question->questiontext; echo "
"; + $question->name = preg_replace("/
/", "", $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;$ianswer[$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 "

$count. ".stripslashes($question->questiontext)."

"; + $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 "
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;$ierr("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;$ilibdir/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 "
count of rows is ". count ($result); + echo "
\n";
+                        $qResult = HtmlSpecialChars($qResult);
+                        echo $qResult;
+                        echo "\n
"; + */ + xml_parser_free($xml_parser); + // $sResult = HtmlSpecialChars($qResult); + //echo("
");
+            //	echo($sResult);
+            //	echo("
"); + + 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 ""; + echo "

Error: $message

"; + echo "

ODBC File DSN: $dsn
"; + echo "
"; + } + + 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; + } +} + +?> diff --git a/mod/quiz/import.php b/mod/quiz/import.php index a723156b86..ee7f77b329 100644 --- a/mod/quiz/import.php +++ b/mod/quiz/import.php @@ -31,17 +31,21 @@ 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)"); diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index d4765f0413..7605b3b1de 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -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