/** * Moves all the files to the destination directory. * * @uses $CFG * @uses $USER * @param string $destination The destination directory. * @return boolean status; */ function save_files($destination) { global $CFG, $USER, $OUTPUT; if (!$this->status) { // preprocess_files hasn't been run $this->preprocess_files(); } // if there are no files, bail before we create an empty directory. if (empty($this->config->somethingtosave)) { return true; } $savedsomething = false; if ($this->status) { if (!(strpos($destination, $CFG->dataroot) === false)) { // take it out for giving to make_upload_directory $destination = substr($destination, strlen($CFG->dataroot) + 1); } if ($destination[strlen($destination) - 1] == '/') { // strip off a trailing / if we have one $destination = substr($destination, 0, -1); } if (!make_upload_directory($destination, true)) { //TODO maybe put this function here instead of moodlelib.php now. $this->status = false; return false; } $destination = $CFG->dataroot . '/' . $destination; // now add it back in so we have a full path $exceptions = array(); //need this later if we're deleting other files. foreach (array_keys($this->files) as $i) { if (!$this->files[$i]['clear']) { // not ok to save continue; } if ($this->config->handlecollisions) { $this->handle_filename_collision($destination, $this->files[$i]); } if (move_uploaded_file($this->files[$i]['tmp_name'], $destination . '/' . $this->files[$i]['name'])) { chmod($destination . '/' . $this->files[$i]['name'], $CFG->directorypermissions); $this->files[$i]['fullpath'] = $destination . '/' . $this->files[$i]['name']; $this->files[$i]['uploadlog'] .= "\n" . get_string('uploadedfile'); $this->files[$i]['saved'] = true; $exceptions[] = $this->files[$i]['name']; // now add it to the log (this is important so we know who to notify if a virus is found later on) clam_log_upload($this->files[$i]['fullpath'], $this->course); $savedsomething = true; } } if ($savedsomething && $this->config->deleteothers) { $this->delete_other_files($destination, $exceptions); } } if (empty($savedsomething)) { $this->status = false; if (empty($this->config->allownull) && !empty($this->inputname) || empty($this->inputname) && empty($this->config->allownullmultiple)) { echo $OUTPUT->notification(get_string('uploadnofilefound')); } return false; } return $this->status; }
function backup_copy_file($from_file, $to_file, $log_clam = false) { global $CFG; if (is_file($from_file)) { //echo "<br />Copying ".$from_file." to ".$to_file; //Debug //$perms=fileperms($from_file); //return copy($from_file,$to_file) && chmod($to_file,$perms); umask(00); if (copy($from_file, $to_file)) { chmod($to_file, $CFG->directorypermissions); if (!empty($log_clam)) { clam_log_upload($to_file, null, true); } return true; } return false; } else { if (is_dir($from_file)) { return backup_copy_dir($from_file, $to_file); } else { //echo "<br />Error: not file or dir ".$from_file; //Debug return false; } } }
/** * Perform required pre-processing, i.e. convert Word file into XML * * Send the Word file to YAWC Online for conversion into XML, using CURL * functions. First check that the file has the right suffix (.doc) and format * (binary Word 2003) required by YAWC. * * A Zip file containing the Question XML file is returned, and this XML file content * is overwritten into the input file, so that the later steps just process the XML * in the normal way. * * @return boolean success */ function importpreprocess() { global $CFG; global $USER; global $COURSE; $import_preprocess_debug = 0; $wordtable_dir = "/question/format/wordtable/"; // Use the default Moodle temporary folder to store temporary files $tmpdir = $CFG->dataroot . "/temp/"; //$debughandle = debug_init($tmpdir . "wordtable.log", $import_preprocess_debug); //debug_write("importpreprocess:this->filename = $this->filename, this->realfilename = $this->realfilename\n"); // Check that the module is registered, and redirect to registration page if not if (!record_exists('config', 'name', 'qformat_wordtable_version')) { notify(get_string('registrationpage', 'qformat_wordtable')); $redirect_url = $CFG->wwwroot . $wordtable_dir . 'register.php?sesskey=' . $USER->sesskey . "&courseid=" . $this->course->id; redirect($redirect_url); } // Check that the file is in Word 2000/2003 format, not HTML, XML, or Word 2007 if (substr($this->realfilename, -4, 4) == 'docx') { notify(get_string('docxnotsupported', 'qformat_wordtable', $this->realfilename)); return false; } else { if (substr($this->realfilename, -3, 3) == 'xml') { notify(get_string('xmlnotsupported', 'qformat_wordtable', $this->realfilename)); return false; } else { if (stripos($this->realfilename, 'htm')) { notify(get_string('htmlnotsupported', 'qformat_wordtable', $this->realfilename)); return false; } else { if (stripos(file_get_contents($this->filename, 0, null, 0, 100), 'html')) { notify(get_string('htmldocnotsupported', 'qformat_wordtable', $this->realfilename)); return false; } } } } // Temporarily copy the Word file so it has a .doc suffix, which is required by YAWC // The uploaded file name has no suffix by default $temp_doc_filename = $tmpdir . clean_filename(basename($this->filename)) . "-" . $this->realfilename; //debug_write("importpreprocess:temp_doc_filename = $temp_doc_filename\n"); if (copy($this->filename, $temp_doc_filename)) { chmod($temp_doc_filename, 0666); clam_log_upload($temp_doc_filename, $COURSE); //debug_write("importpreprocess: $this->filename copied to $temp_doc_filename\n"); } else { notify(get_string("uploadproblem", "", $temp_doc_filename)); } // Get the username and password required for YAWC Online $yol_username = get_record('config', 'name', 'qformat_wordtable_username'); $yol_password = get_record('config', 'name', 'qformat_wordtable_password'); // Now send the file to YAWC to convert it into Moodle Question XML inside a Zip file $yawcurl = 'http://www.yawconline.com/ye_convert1.php'; $yawc_post_data = array("username" => $yol_username->value, "password" => base64_decode($yol_password->value), "downloadZip" => "0", "okUpload" => "Convert", "docFile" => "@" . $temp_doc_filename); //debug_write("importpreprocess: " . print_r($yawc_post_data, true) . "\n"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $yawcurl); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $yawc_post_data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_HEADER, 0); $yawczipdata = curl_exec($ch); curl_close($ch); // Delete the temporary Word file once conversion complete if (!$import_preprocess_debug) { unlink($temp_doc_filename); } // Check that a non-zero length file is returned, and the file is a Zip file //debug_write("importpreprocess:yawczipdata type/length = " . substr($yawczipdata, 0, 2) . "/" . strlen($yawczipdata) . "\n"); if (strlen($yawczipdata) == 0 || substr($yawczipdata, 0, 2) !== "PK") { notify(get_string('conversionfailed', 'qformat_wordtable')); return false; } // Save the Zip file to a regular temporary file, so that we can extract its // contents using the PHP zip library $zipfile = tempnam($tmpdir, "wt-"); //debug_write("importpreprocess:zipfile = " . $zipfile . "\n"); if ($fp = fopen($zipfile, "wb")) { if (($nbytes = fwrite($fp, $yawczipdata)) == 0) { notify(get_string('cannotwritetotempfile', 'qformat_wordtable', $zipfile)); return false; } fclose($fp); } // Open the Zip file and extract the Moodle Question XML file data $zfh = zip_open($zipfile); if ($zfh) { $xmlfile_found = false; while (!$xmlfile_found) { $zip_entry = zip_read($zfh); if (zip_entry_open($zfh, $zip_entry, "r")) { $ze_filename = zip_entry_name($zip_entry); $ze_file_suffix = substr($ze_filename, -3, 3); $ze_filesize = zip_entry_filesize($zip_entry); //debug_write("importpreprocess:zip_entry_name = $ze_filename, $ze_file_suffix, $ze_filesize\n"); if ($ze_file_suffix == "xml") { $xmlfile_found = true; // Found the XML file, so grab the data $xmldata = zip_entry_read($zip_entry, $ze_filesize); //debug_write("importpreprocess:xmldata length = (" . strlen($xmldata) . ")\n"); zip_entry_close($zip_entry); zip_close($zfh); if (!$import_preprocess_debug) { unlink($zipfile); } } } else { notify(get_string('cannotopentempfile', 'qformat_wordtable', $zipfile)); zip_close($zfh); if (!$import_preprocess_debug) { unlink($zipfile); } return false; } } } else { notify(get_string('cannotopentempfile', 'qformat_wordtable', $zipfile)); if (!$import_preprocess_debug) { unlink($zipfile); } return false; } // Now over-write the original Word file with the XML file, so that default XML file handling will work if ($fp = fopen($this->filename, "wb")) { if (($nbytes = fwrite($fp, $xmldata)) == 0) { notify(get_string('cannotwritetotempfile', 'qformat_wordtable', $this->filename)); return false; } fclose($fp); } //notify(get_string('conversionsucceeded', 'qformat_wordtable')); return true; }
function importprocess($filename) { global $CFG, $USER, $strimportquestions, $form, $question_category, $category, $COURSE, $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); clam_log_upload($newfile, $COURSE); } else { notify(get_string("uploadproblem", "", $filename)); } } $filename = $newfile; } print_heading_with_help($strimportquestions, "import", "quiz"); print_simple_box_start("center"); if ($hostname_access_error) { notify("couldn't connect to ODBC Socket Server on " . $hostname_access_error); } echo "<form method=\"post\" action=\"import.php\">"; echo '<fieldset class="invisiblefieldset">'; 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> </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> </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> </td></tr>"; echo "<tr><td> </td><td>"; echo " <input type=\"submit\" name=\"save\" value=\"Connect to Server\" />"; echo "</td></tr>"; echo "</table>"; echo '</fieldset>'; 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); clam_log_upload($newfile, $COURSE); } 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 = question_category_options($COURSE->id, true))) { error("No categories!"); } print_heading_with_help($strimportquestions, "import", "quiz"); print_simple_box_start("center"); echo "<form method=\"post\" action=\"import.php\">"; echo '<fieldset class="invisiblefieldset">'; 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> </td>"; echo "</tr><tr><td> </td><td>"; echo " <input type=\"submit\" name=\"save\" value=\"Import Questions\" />"; echo "</td></tr>"; echo "</table>"; echo '</fieldset>'; 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 = $this->defaultquestion(); if ($qrec[9] != "") { $question->image = $qrec[9]; } // 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; } 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[0] = " "; $question->fraction[0] = 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->createdby = $USER->id; $question->timecreated = time(); if (!($question->id = insert_record("question", $question))) { error("Could not insert new question!"); } $this->questionids[] = $question->id; // Now to save all the answers and type-specific options $result = 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; } // Give the question a unique version stamp determined by question_hash() set_field('question', 'version', question_hash($question), 'id', $question->id); } $this->deletedatabase($filename); return true; }
/** * Moves all the files to the destination directory. * * @uses $CFG * @uses $USER * @param string $destination The destination directory. * @return boolean status; */ function save_files($destination) { global $CFG, $USER; $textlib = textlib_get_instance(); if (!$this->status) { // preprocess_files hasn't been run $this->preprocess_files(); } if ($this->status) { if (!($textlib->strpos($destination, $CFG->dataroot) === false)) { // take it out for giving to make_upload_directory $destination = $textlib->substr($destination, $textlib->strlen($CFG->dataroot)); } if ($destination[$textlib->strlen($destination) - 1] == '/') { // strip off a trailing / if we have one $destination = $textlib->substr($destination, 0, -1); } if (!make_upload_directory($destination, true)) { //TODO maybe put this function here instead of moodlelib.php now. $this->status = false; return false; } $destination = $CFG->dataroot . $destination; // now add it back in so we have a full path $exceptions = array(); //need this later if we're deleting other files. foreach (array_keys($this->files) as $i) { if (!$this->files[$i]['clear']) { // not ok to save continue; } if ($this->config->handlecollisions) { $this->handle_filename_collision($destination, $this->files[$i]); } if (move_uploaded_file($this->files[$i]['tmp_name'], $destination . '/' . $this->files[$i]['name'])) { chmod($destination . '/' . $this->files[$i]['name'], $CFG->filepermissions); $this->files[$i]['fullpath'] = $destination . '/' . $this->files[$i]['name']; $this->files[$i]['uploadlog'] .= "\n" . gettext('File uploaded successfully'); $this->files[$i]['saved'] = true; $exceptions[] = $this->files[$i]['name']; // now add it to the log (this is important so we know who to notify if a virus is found later on) clam_log_upload($this->files[$i]['fullpath']); $savedsomething = true; } } if ($savedsomething && $this->config->deleteothers) { $this->delete_other_files($destination, $exceptions); } } if (empty($savedsomething)) { $this->status = false; if (empty($this->config->allownull) && !empty($this->inputname) || empty($this->inputname) && empty($this->config->allownullmultiple)) { notify(gettext('No file was found - are you sure you selected one to upload?')); } return false; } return $this->status; }