/** * Do the export * For most types this should not need to be overrided * @return stored_file */ public function exportprocess() { global $CFG, $OUTPUT, $DB, $USER; // get the questions (from database) in this category // only get q's with no parents (no cloze subquestions specifically) if ($this->category) { $questions = get_questions_category($this->category, true); } else { $questions = $this->questions; } $count = 0; // results are first written into string (and then to a file) // so create/initialize the string here $expout = ""; // track which category questions are in // if it changes we will record the category change in the output // file if selected. 0 means that it will get printed before the 1st question $trackcategory = 0; // iterate through questions foreach ($questions as $question) { // used by file api $contextid = $DB->get_field('question_categories', 'contextid', array('id' => $question->category)); $question->contextid = $contextid; // do not export hidden questions if (!empty($question->hidden)) { continue; } // do not export random questions if ($question->qtype == 'random') { continue; } // check if we need to record category change if ($this->cattofile) { if ($question->category != $trackcategory) { $trackcategory = $question->category; $categoryname = $this->get_category_path($trackcategory, $this->contexttofile); // create 'dummy' question for category export $dummyquestion = new stdClass(); $dummyquestion->qtype = 'category'; $dummyquestion->category = $categoryname; $dummyquestion->name = 'Switch category to ' . $categoryname; $dummyquestion->id = 0; $dummyquestion->questiontextformat = ''; $dummyquestion->contextid = 0; $expout .= $this->writequestion($dummyquestion) . "\n"; } } // export the question displaying message $count++; if (question_has_capability_on($question, 'view', $question->category)) { $expout .= $this->writequestion($question, $contextid) . "\n"; } } // continue path for following error checks $course = $this->course; $continuepath = "$CFG->wwwroot/question/export.php?courseid=$course->id"; // did we actually process anything if ($count==0) { print_error('noquestions', 'question', $continuepath); } // final pre-process on exported data $expout = $this->presave_process($expout); return $expout; }
/** * exports the questions in a question category to the given location * * The parent class method was overridden because the IMS export consists of multiple files * * @param string $filename the directory name which will hold the exported files * @return boolean - or errors out */ function exportprocess() { global $CFG; $courseid = $this->course->id; // create a directory for the exports (if not already existing) if (!($export_dir = make_upload_directory($this->question_get_export_dir() . '/' . $this->filename))) { error(get_string('cannotcreatepath', 'quiz', $export_dir)); } $path = $CFG->dataroot . '/' . $this->question_get_export_dir() . '/' . $this->filename; // get the questions (from database) in this category // $questions = get_records("question","category",$this->category->id); $questions = get_questions_category($this->category); notify("Exporting " . count($questions) . " questions."); $count = 0; // create the imsmanifest file $smarty =& $this->init_smarty(); $this->add_qti_info($questions); // copy files used by the main questions to the export directory $result = $this->handle_questions_media($questions, $path, $courseid); if ($result !== true) { notify(implode("<br />", $result)); } $manifestquestions = $this->objects_to_array($questions); $manifestid = str_replace(array(':', '/'), array('-', '_'), "question_category_{$this->category->id}---{$CFG->wwwroot}"); $smarty->assign('externalfiles', 1); $smarty->assign('manifestidentifier', $manifestid); $smarty->assign('quiztitle', "question_category_{$this->category->id}"); $smarty->assign('quizinfo', "All questions in category {$this->category->id}"); $smarty->assign('questions', $manifestquestions); $smarty->assign('lang', $this->lang); $smarty->error_reporting = 99; $expout = $smarty->fetch('imsmanifest.tpl'); $filepath = $path . '/imsmanifest.xml'; if (empty($expout)) { error("Unkown error - empty imsmanifest.xml"); } if (!($fh = fopen($filepath, "w"))) { error("Cannot open for writing: {$filepath}"); } if (!fwrite($fh, $expout)) { error("Cannot write exported questions to {$filepath}"); } fclose($fh); // iterate through questions foreach ($questions as $question) { // results are first written into string (and then to a file) $count++; echo "<hr /><p><b>{$count}</b>. " . stripslashes($question->questiontext) . "</p>"; $expout = $this->writequestion($question, null, true, $path) . "\n"; $expout = $this->presave_process($expout); $filepath = $path . '/' . $this->get_assesment_item_id($question) . ".xml"; if (!($fh = fopen($filepath, "w"))) { error("Cannot open for writing: {$filepath}"); } if (!fwrite($fh, $expout)) { error("Cannot write exported questions to {$filepath}"); } fclose($fh); } // zip files into single export file zip_files(array($path), "{$path}.zip"); // remove the temporary directory remove_dir($path); return true; }
/** * exports the questions in a question category to the given location * * The parent class method was overridden because the IMS export consists of multiple files * * @param string $filename the directory name which will hold the exported files * @return bool - or errors out */ public function exportprocess() { global $CFG, $OUTPUT, $USER; $courseid = $this->course->id; $path = 'temp/qformat_qti_two/' . $USER->id . '/' . $this->filename; // create a directory for the exports (if not already existing) if (!make_upload_directory($path)) { throw new moodle_exception('cannotcreatepath', 'question', '', $path); } $path = $CFG->dataroot . '/' . $path; // get the questions (from database) in this category $questions = get_questions_category($this->category); // create the imsmanifest file $smarty =& $this->init_smarty(); $this->add_qti_info($questions); // copy files used by the main questions to the export directory $result = $this->handle_questions_media($questions, $path, $courseid); if ($result !== true) { throw new coding_exception(implode("<br />", $result)); } $manifestquestions = $this->objects_to_array($questions); $manifestid = str_replace(array(':', '/'), array('-', '_'), "question_category_{$this->category->id}---{$CFG->wwwroot}"); $smarty->assign('externalfiles', 1); $smarty->assign('manifestidentifier', $manifestid); $smarty->assign('quiztitle', "question_category_{$this->category->id}"); $smarty->assign('quizinfo', "All questions in category {$this->category->id}"); $smarty->assign('questions', $manifestquestions); $smarty->assign('lang', $this->lang); $smarty->error_reporting = 99; $expout = $smarty->fetch('imsmanifest.tpl'); $filepath = $path . '/imsmanifest.xml'; if (empty($expout)) { print_error('emptyxml', 'question'); } if (!($fh = fopen($filepath, "w"))) { print_error('cannotopenforwriting', 'question', '', $filepath); } if (!fwrite($fh, $expout)) { print_error('cannotwriteto', 'question', '', $filepath); } fclose($fh); // iterate through questions foreach ($questions as $question) { // results are first written into string (and then to a file) $expout = $this->writequestion($question, null, true, $path) . "\n"; $expout = $this->presave_process($expout); $filepath = $path . '/' . $this->get_assesment_item_id($question) . ".xml"; if (!($fh = fopen($filepath, "w"))) { print_error('cannotopenforwriting', 'question', '', $filepath); } if (!fwrite($fh, $expout)) { print_error('cannotwriteto', 'question', '', $filepath); } fclose($fh); } // zip files into single export file zip_files(array($path), "{$path}.zip"); // remove the temporary directory remove_dir($path); return true; }
/** * Do the export * For most types this should not need to be overrided * @return boolean success */ function exportprocess() { global $CFG; // create a directory for the exports (if not already existing) if (!($export_dir = make_upload_directory($this->question_get_export_dir()))) { error(get_string('cannotcreatepath', 'quiz', $export_dir)); } $path = $CFG->dataroot . '/' . $this->question_get_export_dir(); // get the questions (from database) in this category // only get q's with no parents (no cloze subquestions specifically) if ($this->category) { $questions = get_questions_category($this->category, true); } else { $questions = $this->questions; } notify(get_string('exportingquestions', 'quiz')); $count = 0; // results are first written into string (and then to a file) // so create/initialize the string here $expout = ""; // track which category questions are in // if it changes we will record the category change in the output // file if selected. 0 means that it will get printed before the 1st question $trackcategory = 0; // iterate through questions foreach ($questions as $question) { // do not export hidden questions if (!empty($question->hidden)) { continue; } // do not export random questions if ($question->qtype == RANDOM) { continue; } // check if we need to record category change if ($this->cattofile) { if ($question->category != $trackcategory) { $trackcategory = $question->category; $categoryname = $this->get_category_path($trackcategory, '/', $this->contexttofile); // create 'dummy' question for category export $dummyquestion = new object(); $dummyquestion->qtype = 'category'; $dummyquestion->category = $categoryname; $dummyquestion->name = "switch category to {$categoryname}"; $dummyquestion->id = 0; $dummyquestion->questiontextformat = ''; $expout .= $this->writequestion($dummyquestion) . "\n"; } } // export the question displaying message $count++; echo "<hr /><p><b>{$count}</b>. " . $this->format_question_text($question) . "</p>"; if (question_has_capability_on($question, 'view', $question->category)) { $expout .= $this->writequestion($question) . "\n"; } } // continue path for following error checks $course = $this->course; $continuepath = "{$CFG->wwwroot}/question/export.php?courseid={$course->id}"; // did we actually process anything if ($count == 0) { print_error('noquestions', 'quiz', $continuepath); } // final pre-process on exported data $expout = $this->presave_process($expout); // write file $filepath = $path . "/" . $this->filename . $this->export_file_extension(); if (!($fh = fopen($filepath, "w"))) { print_error('cannotopen', 'quiz', $continuepath, $filepath); } if (!fwrite($fh, $expout, strlen($expout))) { print_error('cannotwrite', 'quiz', $continuepath, $filepath); } fclose($fh); return true; }
include $CFG->dirroot . "/mod/{$cm->modname}/tabs.php"; $exportfilename = default_export_filename($COURSE, $category); $export_form = new question_export__good_questions_form($thispageurl, array('contexts' => array($contexts->lowest()), 'defaultcategory' => $pagevars['cat'], 'defaultfilename' => $exportfilename, 'qcreate' => $qcreate)); if ($from_form = $export_form->get_data()) { /// Filename if (!is_readable($CFG->dirroot . "/question/format/{$from_form->format}/format.php")) { error("Format not known ({$from_form->format})"); } // load parent class for import/export require_once $CFG->dirroot . "/question/format.php"; // and then the class for the selected format require_once $CFG->dirroot . "/question/format/{$from_form->format}/format.php"; $classname = "qformat_{$from_form->format}"; $qformat = new $classname(); $qformat->setContexts($contexts->having_one_edit_tab_cap('export')); $questions = get_questions_category($category, true); if ($qcreate->graderatio != 100 && $from_form->betterthangrade != 0) { //filter questions by grade $qkeys = array(); foreach ($questions as $question) { $qkeys[] = $question->id; } $questionlist = join($qkeys, ','); $sql = 'SELECT questionid, grade FROM ' . $CFG->prefix . 'qcreate_grades ' . 'WHERE questionid IN (' . $questionlist . ') AND grade >= ' . $from_form->betterthangrade; if ($goodquestions = get_records_sql($sql)) { foreach ($questions as $zbkey => $question) { if (!array_key_exists($question->id, $goodquestions)) { unset($questions[$zbkey]); } } } else {
public function get_questions($category, $include_category = false, $include_hidden = false) { $result = array(); $questions = get_questions_category($category); foreach ($questions as $question) { if ((!$question->hidden || $include_category) && ($question->parent == 0 || $include_hidden)) { $result[] = $question; } } return $result; }
/** * exports the questions in a question category to the given location * * The parent class method was overridden because the IMS export consists of multiple files * * @param string $filename the directory name which will hold the exported files * @return bool - or errors out */ public function exportprocess() { global $CFG, $OUTPUT, $USER, $DB; $courseid = $this->course->id; // Continue path for following error checks. $continuepath = "{$CFG->wwwroot}/question/export.php?courseid={$courseid}"; // Create a temporary directory for the exports (if not already existing). $uniquecode = time(); $this->tempdir = 'qformat_qtitwo/' . $USER->id . '/' . $uniquecode; if (!($path = make_temp_directory($this->tempdir))) { throw new moodle_exception('cannotcreatepath', 'question', '', $path); print_error('cannotcreatepath', 'quiz', '', $continuepath); } // Get the questions (from database) in this category. $questions = get_questions_category($this->category); $count = 0; // Create the imsmanifest file. $smarty =& $this->init_smarty(); $this->add_qti_info($questions); $manifestquestions = $this->objects_to_array($questions); $manifestid = str_replace(array(':', '/'), array('-', '_'), "question_category_{$this->category->id}---{$CFG->wwwroot}"); $smarty->assign('externalfiles', 1); $smarty->assign('manifestidentifier', $manifestid); $smarty->assign('quiztitle', "question_category_{$this->category->id}"); $smarty->assign('quizinfo', "All questions in category {$this->category->id}"); $smarty->assign('questions', $manifestquestions); $smarty->assign('lang', $this->lang); $smarty->error_reporting = 99; $expout = $smarty->fetch('imsmanifest.tpl'); $filepath = $path . '/imsmanifest.xml'; if (empty($expout)) { print_error('emptyxml', 'question', $continuepath); } if (!($fh = fopen($filepath, "w"))) { print_error('cannotopenforwriting', 'question', '', $continuepath); } if (!fwrite($fh, $expout)) { print_error('cannotwriteto', 'question', '', $continuepath); } fclose($fh); $this->xml_entitize($questions); // Iterate through questions. foreach ($questions as $question) { // Do not export hidden questions. if (!empty($question->hidden)) { continue; } // Do not export random questions. if ($question->qtype == 'random') { continue; } // used by file api $contextid = $DB->get_field('question_categories', 'contextid', array('id' => $question->category)); $question->contextid = $contextid; // Results are first written into string (and then to a file). $count++; $expout = $this->writequestion($question, null, true, $path) . "\n"; $expout = $this->presave_process($expout); $filepath = $path . '/' . $this->get_assesment_item_id($question) . ".xml"; if (!($fh = fopen($filepath, "w"))) { print_error('cannotopenforwriting', 'question', '', $continuepath); } if (!fwrite($fh, $expout)) { print_error('cannotwriteto', 'question', '', $continuepath); } fclose($fh); } $this->copy_resources($questions, $this->tempdir); // Get the list of files in directory. $filestemp = get_directory_list($path, '', false, true, true); $files = array(); foreach ($filestemp as $file) { // Add zip paths and fs paths to all them. $files[$file] = $path . '/' . $file; } // Get the zip packer. $zippacker = get_file_packer('application/zip'); // Zip files. $zipfile = $path . ' /qti2.zip'; $zippacker->archive_to_pathname($files, $zipfile); $zipcontent = file_get_contents($zipfile); // Remove the temporary directory. fulldelete($path); return $zipcontent; }
/** * Returns welcome message * @return string welcome message */ public static function get_quiz() { global $USER, $DB, $CFG; $randomcolors = array('green', 'yellow', 'blue', 'red', 'purple'); $randomicons = array('entertainment', 'sports', 'music', 'tvmovies', 'science', 'geography', 'history', 'knowledge', 'food'); $randomsingletypes = array('single-select-item', 'single-select'); //Parameter validation $params = self::validate_parameters(self::get_quiz_parameters(), array()); //Context validation //self::validate_context(context_user::get_instance($USER->id)); //Capability checking //if (!has_capability('moodle/user:viewdetails', $context)) { // throw new moodle_exception('cannotviewprofile'); //} $courses = enrol_get_users_courses($USER->id, true, 'id, shortname, fullname, idnumber, visible'); $result = array(); foreach ($courses as $course) { // Find all questions the user is allowed to see $coursecontext = context_course::instance($course->id); $questions = array(); require_once $CFG->dirroot . "/question/editlib.php"; $category = question_get_default_category($coursecontext->id); $catquestions = get_questions_category($category); // only keep multichoice yet. foreach ($catquestions as $question) { if ($question->qtype == "multichoice") { $questions[$question->id] = $question; } } if (!empty($questions)) { // pick random theme color and icon. $color = $randomcolors[array_rand($randomcolors)]; $icon = $randomicons[array_rand($randomicons)]; $quizresult = new stdClass(); $quizresult->name = $course->shortname; $quizresult->id = $icon; $quizresult->theme = $color; $quizresult->quizzes = array(); // Only get 8 questions maxim $i = 0; foreach ($questions as $question) { if ($i < 8) { $i++; // Convert them into JSON expected code $questionresult = new stdClass(); $questionresult->question = clean_param($question->questiontext, PARAM_TEXT); $questionresult->options = array(); $answernum = 0; $jsonanswer = array(); foreach ($question->options->answers as $answer) { // Find out if the answer is the correct one (obviouly we don't support multiple answer yet) if ($answer->fraction > 0) { $jsonanswer[] = $answernum; } $questionresult->options[] = clean_param($answer->answer, PARAM_TEXT); $answernum++; } // Detect moodeka quiz type. if (count($jsonanswer) > 1) { $type = 'multi-select'; } else { if ($answernum == 4 and rand(0, 1)) { $type = 'four-quarter'; } else { $type = $randomsingletypes[array_rand($randomsingletypes)]; } } $questionresult->answer = $jsonanswer; $questionresult->type = $type; $quizresult->quizzes[] = $questionresult; } } $result[] = $quizresult; } } return $result; }