/** * Add question-type specific form fields. * * @param object $mform the form being built. */ protected function definition_inner($mform) { $mform->removeElement('defaultmark'); $mform->addElement('hidden', 'defaultmark', '1'); $mform->removeElement('generalfeedback'); $mform->addElement('advcheckbox', 'autoplay', get_string('autoplay', 'qtype_turmultiplechoice'), null, null, array(0, 1)); $mform->addHelpButton('autoplay', 'autoplay', 'qtype_turmultiplechoice'); $mform->setDefault('autoplay', 0); $menu = array(get_string('answersingleno', 'qtype_turmultiplechoice'), get_string('answersingleyes', 'qtype_turmultiplechoice')); $mform->addElement('select', 'single', get_string('answerhowmany', 'qtype_turmultiplechoice'), $menu); $mform->setDefault('single', 0); // 'Image to display' filemanager $mform->addElement('filemanager', 'questionimage', 'Image to display', null, array('maxfiles' => 1)); // TODO: Use lang string // 'Choose soundfile for question' filemanager $mform->addElement('filemanager', 'questionsound', 'Choose soundfile for question', null, array('maxfiles' => 1, 'accepted_types' => array('.mp3'))); // TODO: Use lang string $question_difficulties = array(); $question_difficulties[0] = get_string('q_easy1', 'qtype_turmultiplechoice'); $question_difficulties[1] = get_string('q_easy2', 'qtype_turmultiplechoice'); $question_difficulties[2] = get_string('q_easy3', 'qtype_turmultiplechoice'); $question_difficulties[3] = get_string('q_medium1', 'qtype_turmultiplechoice'); $question_difficulties[4] = get_string('q_medium2', 'qtype_turmultiplechoice'); $question_difficulties[5] = get_string('q_medium3', 'qtype_turmultiplechoice'); $question_difficulties[6] = get_string('q_hard1', 'qtype_turmultiplechoice'); $question_difficulties[7] = get_string('q_hard2', 'qtype_turmultiplechoice'); $question_difficulties[8] = get_string('q_hard3', 'qtype_turmultiplechoice'); $mform->addElement('select', 'qdifficulty', get_string('qdifficulty', 'qtype_turmultiplechoice'), $question_difficulties); $mform->setDefault('qdifficulty', 0); $mform->addElement('hidden', 'shuffleanswers', 1); $this->add_per_answer_fields($mform, get_string('choiceno', 'qtype_turmultiplechoice', '{no}'), question_bank::fraction_options_full(), max(4, QUESTION_NUMANS_START), 4); $this->add_combined_feedback_fields(true); $mform->disabledIf('shownumcorrect', 'single', 'eq', 1); }
/** * Add question-type specific form fields. * * @param object $mform the form being built. */ protected function definition_inner($mform) { $menu = array( get_string('answersingleno', 'qtype_multichoice'), get_string('answersingleyes', 'qtype_multichoice'), ); $mform->addElement('select', 'single', get_string('answerhowmany', 'qtype_multichoice'), $menu); $mform->setDefault('single', 1); $mform->addElement('advcheckbox', 'shuffleanswers', get_string('shuffleanswers', 'qtype_multichoice'), null, null, array(0, 1)); $mform->addHelpButton('shuffleanswers', 'shuffleanswers', 'qtype_multichoice'); $mform->setDefault('shuffleanswers', 1); $mform->addElement('select', 'answernumbering', get_string('answernumbering', 'qtype_multichoice'), qtype_multichoice::get_numbering_styles()); $mform->setDefault('answernumbering', 'abc'); $this->add_per_answer_fields($mform, get_string('choiceno', 'qtype_multichoice', '{no}'), question_bank::fraction_options_full(), max(5, QUESTION_NUMANS_START)); $this->add_combined_feedback_fields(true); $mform->disabledIf('shownumcorrect', 'single', 'eq', 1); $this->add_interactive_settings(true, true); }
protected function definition() { global $CFG, $PAGE; parent::definition(); $mform = $this->_form; $mform->addElement("hidden", self::EDITOR_INFO_ELEMENT_NAME); $mform->setType(self::EDITOR_INFO_ELEMENT_NAME, PARAM_RAW); $mform->setDefault(self::EDITOR_INFO_ELEMENT_NAME, json_encode(array("image_server" => get_config('omero', 'omero_restendpoint'), "viewer_model_server" => $CFG->omero_image_server, "image_info_container_id" => $this->image_info_container_id, "image_selector_id" => $this->image_selector_id, "answer_header" => "id_answerhdr", "fraction_options" => question_bank::fraction_options_full()))); $PAGE->requires->js_call_amd("qtype_omeromultichoice/question-editor-multichoice", "main", array(self::EDITOR_INFO_ELEMENT_NAME)); }
public function test_match_grade_options() { $gradeoptions = question_bank::fraction_options_full(); $this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.3333333, 'error')); $this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.333333, 'error')); $this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.33333, 'error')); $this->assertFalse(match_grade_options($gradeoptions, 0.3333, 'error')); $this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.3333333, 'nearest')); $this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.333333, 'nearest')); $this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.33333, 'nearest')); $this->assertEquals(0.3333333, match_grade_options($gradeoptions, 0.33, 'nearest')); $this->assertEquals(-0.1428571, match_grade_options($gradeoptions, -0.15, 'nearest')); }
public function test_fraction_options_full() { $fractions = question_bank::fraction_options_full(); $this->assertSame(get_string('none'), reset($fractions)); $this->assertSame('0.0', key($fractions)); $this->assertSame('-100%', end($fractions)); $this->assertSame('-1.0', key($fractions)); array_shift($fractions); array_pop($fractions); array_pop($fractions); $this->assertSame('100%', reset($fractions)); $this->assertSame('1.0', key($fractions)); $this->assertSame('-83.33333%', end($fractions)); $this->assertSame('-0.8333333', key($fractions)); }
/** * Process the file * This method should not normally be overidden * @param object $category * @return bool success */ public function importprocess($category) { global $USER, $CFG, $DB, $OUTPUT; $context = $category->context; $this->importcontext = $context; // reset the timer in case file upload was slow set_time_limit(0); // STAGE 1: Parse the file echo $OUTPUT->notification(get_string('parsingquestions', 'question'), 'notifysuccess'); if (! $lines = $this->readdata($this->filename)) { echo $OUTPUT->notification(get_string('cannotread', 'question')); return false; } if (!$questions = $this->readquestions($lines, $context)) { // Extract all the questions echo $OUTPUT->notification(get_string('noquestionsinfile', 'question')); return false; } // STAGE 2: Write data to database echo $OUTPUT->notification(get_string('importingquestions', 'question', $this->count_questions($questions)), 'notifysuccess'); // check for errors before we continue if ($this->stoponerror and ($this->importerrors>0)) { echo $OUTPUT->notification(get_string('importparseerror', 'question')); return true; } // get list of valid answer grades $gradeoptionsfull = question_bank::fraction_options_full(); // check answer grades are valid // (now need to do this here because of 'stop on error': MDL-10689) $gradeerrors = 0; $goodquestions = array(); foreach ($questions as $question) { if (!empty($question->fraction) and (is_array($question->fraction))) { $fractions = $question->fraction; $answersvalid = true; // in case they are! foreach ($fractions as $key => $fraction) { $newfraction = match_grade_options($gradeoptionsfull, $fraction, $this->matchgrades); if ($newfraction === false) { $answersvalid = false; } else { $fractions[$key] = $newfraction; } } if (!$answersvalid) { echo $OUTPUT->notification(get_string('invalidgrade', 'question')); ++$gradeerrors; continue; } else { $question->fraction = $fractions; } } $goodquestions[] = $question; } $questions = $goodquestions; // check for errors before we continue if ($this->stoponerror && $gradeerrors > 0) { return false; } // count number of questions processed $count = 0; foreach ($questions as $question) { // Process and store each question // reset the php timeout set_time_limit(0); // check for category modifiers if ($question->qtype == 'category') { if ($this->catfromfile) { // find/create category object $catpath = $question->category; $newcategory = $this->create_category_path($catpath); if (!empty($newcategory)) { $this->category = $newcategory; } } continue; } $question->context = $context; $count++; echo "<hr /><p><b>$count</b>. ".$this->format_question_text($question)."</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(); $question->modifiedby = $USER->id; $question->timemodified = time(); $question->id = $DB->insert_record('question', $question); if (isset($question->questiontextfiles)) { foreach ($question->questiontextfiles as $file) { question_bank::get_qtype($question->qtype)->import_file( $context, 'question', 'questiontext', $question->id, $file); } } if (isset($question->generalfeedbackfiles)) { foreach ($question->generalfeedbackfiles as $file) { question_bank::get_qtype($question->qtype)->import_file( $context, 'question', 'generalfeedback', $question->id, $file); } } $this->questionids[] = $question->id; // Now to save all the answers and type-specific options $result = question_bank::get_qtype($question->qtype)->save_question_options($question); if (!empty($CFG->usetags) && isset($question->tags)) { require_once($CFG->dirroot . '/tag/lib.php'); tag_set('question', $question->id, $question->tags); } if (!empty($result->error)) { echo $OUTPUT->notification($result->error); return false; } if (!empty($result->notice)) { echo $OUTPUT->notification($result->notice); return true; } // Give the question a unique version stamp determined by question_hash() $DB->set_field('question', 'version', question_hash($question), array('id' => $question->id)); } return true; }
/** * Returns list of 'allowed' grades for grade selection * formatted suitably for dropdown box function * * @deprecated since 2.1. Use {@link question_bank::fraction_options()} or * {@link question_bank::fraction_options_full()} instead. * * @return object ->gradeoptionsfull full array ->gradeoptions +ve only */ function get_grade_options() { $grades = new stdClass(); $grades->gradeoptions = question_bank::fraction_options(); $grades->gradeoptionsfull = question_bank::fraction_options_full(); return $grades; }
protected function definition_inner($mform) { $label = get_string('sharedwildcards', 'qtype_calculated'); $mform->addElement('hidden', 'initialcategory', 1); $mform->addElement('hidden', 'reload', 1); $mform->setType('initialcategory', PARAM_INT); $mform->setType('reload', PARAM_BOOL); $html2 = ''; $mform->insertElementBefore($mform->createElement('static', 'listcategory', $label, $html2), 'name'); if (isset($this->question->id)) { $mform->insertElementBefore($mform->createElement('static', 'initialname', get_string('questionstoredname', 'qtype_calculated'), $this->initialname), 'name'); } $addfieldsname = 'updatecategory'; $addstring = get_string('updatecategory', 'qtype_calculated'); $mform->registerNoSubmitButton($addfieldsname); $this->editasmultichoice = 1; $mform->insertElementBefore($mform->createElement('submit', $addfieldsname, $addstring), 'listcategory'); $mform->registerNoSubmitButton('createoptionbutton'); $mform->addElement('hidden', 'multichoice', $this->editasmultichoice); $mform->setType('multichoice', PARAM_INT); $menu = array(get_string('answersingleno', 'qtype_multichoice'), get_string('answersingleyes', 'qtype_multichoice')); $mform->addElement('select', 'single', get_string('answerhowmany', 'qtype_multichoice'), $menu); $mform->setDefault('single', 1); $mform->addElement('advcheckbox', 'shuffleanswers', get_string('shuffleanswers', 'qtype_multichoice'), null, null, array(0, 1)); $mform->addHelpButton('shuffleanswers', 'shuffleanswers', 'qtype_multichoice'); $mform->setDefault('shuffleanswers', 1); $numberingoptions = question_bank::get_qtype('multichoice')->get_numbering_styles(); $mform->addElement('select', 'answernumbering', get_string('answernumbering', 'qtype_multichoice'), $numberingoptions); $mform->setDefault('answernumbering', 'abc'); $this->add_per_answer_fields($mform, get_string('choiceno', 'qtype_multichoice', '{no}'), question_bank::fraction_options_full(), max(5, QUESTION_NUMANS_START)); $mform->addHelpButton('answeroptions[0]', 'answeroptions', 'qtype_calculatedmulti'); $repeated = array(); $nounits = optional_param('nounits', 1, PARAM_INT); $mform->addElement('hidden', 'nounits', $nounits); $mform->setType('nounits', PARAM_INT); $mform->setConstants(array('nounits' => $nounits)); for ($i = 0; $i < $nounits; $i++) { $mform->addElement('hidden', 'unit' . "[{$i}]", optional_param("unit[{$i}]", '', PARAM_NOTAGS)); $mform->setType('unit' . "[{$i}]", PARAM_NOTAGS); $mform->addElement('hidden', 'multiplier' . "[{$i}]", optional_param("multiplier[{$i}]", '', PARAM_FLOAT)); $mform->setType("multiplier[{$i}]", PARAM_FLOAT); } $this->add_combined_feedback_fields(true); $mform->disabledIf('shownumcorrect', 'single', 'eq', 1); $this->add_interactive_settings(true, true); // Hidden elements. $mform->addElement('hidden', 'synchronize', ''); $mform->setType('synchronize', PARAM_INT); if (isset($this->question->options) && isset($this->question->options->synchronize)) { $mform->setDefault('synchronize', $this->question->options->synchronize); } else { $mform->setDefault('synchronize', 0); } $mform->addElement('hidden', 'wizard', 'datasetdefinitions'); $mform->setType('wizard', PARAM_ALPHA); }
/** * Process the file * This method should not normally be overidden * @param object $category * @return bool success */ public function importprocess($category) { global $USER, $CFG, $DB, $OUTPUT; // Raise time and memory, as importing can be quite intensive. core_php_time_limit::raise(); raise_memory_limit(MEMORY_EXTRA); // STAGE 1: Parse the file echo $OUTPUT->notification(get_string('parsingquestions', 'question'), 'notifysuccess'); if (!($lines = $this->readdata($this->filename))) { echo $OUTPUT->notification(get_string('cannotread', 'question')); return false; } if (!($questions = $this->readquestions($lines))) { // Extract all the questions echo $OUTPUT->notification(get_string('noquestionsinfile', 'question')); return false; } // STAGE 2: Write data to database echo $OUTPUT->notification(get_string('importingquestions', 'question', $this->count_questions($questions)), 'notifysuccess'); // check for errors before we continue if ($this->stoponerror and $this->importerrors > 0) { echo $OUTPUT->notification(get_string('importparseerror', 'question')); return true; } // get list of valid answer grades $gradeoptionsfull = question_bank::fraction_options_full(); // check answer grades are valid // (now need to do this here because of 'stop on error': MDL-10689) $gradeerrors = 0; $goodquestions = array(); foreach ($questions as $question) { if (!empty($question->fraction) and is_array($question->fraction)) { $fractions = $question->fraction; $invalidfractions = array(); foreach ($fractions as $key => $fraction) { $newfraction = match_grade_options($gradeoptionsfull, $fraction, $this->matchgrades); if ($newfraction === false) { $invalidfractions[] = $fraction; } else { $fractions[$key] = $newfraction; } } if ($invalidfractions) { echo $OUTPUT->notification(get_string('invalidgrade', 'question', implode(', ', $invalidfractions))); ++$gradeerrors; continue; } else { $question->fraction = $fractions; } } $goodquestions[] = $question; } $questions = $goodquestions; // check for errors before we continue if ($this->stoponerror && $gradeerrors > 0) { return false; } // count number of questions processed $count = 0; foreach ($questions as $question) { // Process and store each question $transaction = $DB->start_delegated_transaction(); // reset the php timeout core_php_time_limit::raise(); // check for category modifiers if ($question->qtype == 'category') { if ($this->catfromfile) { // find/create category object $catpath = $question->category; $newcategory = $this->create_category_path($catpath); if (!empty($newcategory)) { $this->category = $newcategory; } } $transaction->allow_commit(); continue; } $question->context = $this->importcontext; $count++; echo "<hr /><p><b>{$count}</b>. " . $this->format_question_text($question) . "</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(); $question->modifiedby = $USER->id; $question->timemodified = time(); $fileoptions = array('subdirs' => true, 'maxfiles' => -1, 'maxbytes' => 0); $question->id = $DB->insert_record('question', $question); if (isset($question->questiontextitemid)) { $question->questiontext = file_save_draft_area_files($question->questiontextitemid, $this->importcontext->id, 'question', 'questiontext', $question->id, $fileoptions, $question->questiontext); } else { if (isset($question->questiontextfiles)) { foreach ($question->questiontextfiles as $file) { question_bank::get_qtype($question->qtype)->import_file($this->importcontext, 'question', 'questiontext', $question->id, $file); } } } if (isset($question->generalfeedbackitemid)) { $question->generalfeedback = file_save_draft_area_files($question->generalfeedbackitemid, $this->importcontext->id, 'question', 'generalfeedback', $question->id, $fileoptions, $question->generalfeedback); } else { if (isset($question->generalfeedbackfiles)) { foreach ($question->generalfeedbackfiles as $file) { question_bank::get_qtype($question->qtype)->import_file($this->importcontext, 'question', 'generalfeedback', $question->id, $file); } } } $DB->update_record('question', $question); $this->questionids[] = $question->id; // Now to save all the answers and type-specific options $result = question_bank::get_qtype($question->qtype)->save_question_options($question); if (!empty($CFG->usetags) && isset($question->tags)) { require_once $CFG->dirroot . '/tag/lib.php'; tag_set('question', $question->id, $question->tags, 'core_question', $question->context->id); } if (!empty($result->error)) { echo $OUTPUT->notification($result->error); // Can't use $transaction->rollback(); since it requires an exception, // and I don't want to rewrite this code to change the error handling now. $DB->force_transaction_rollback(); return false; } $transaction->allow_commit(); if (!empty($result->notice)) { echo $OUTPUT->notification($result->notice); return true; } // Give the question a unique version stamp determined by question_hash() $DB->set_field('question', 'version', question_hash($question), array('id' => $question->id)); } return true; }
/** * Defines the answers section: * the default answer section has no header an * a set of default hidden fields (see standard answer fields) * to represent a single answer. * It calls the <pre>add_per_answer_fields</pre> method * to define the list of fields to represent an answer: * such a method actually calls <pre>add_per_answer_fields</pre>. * * * @return mixed */ protected function define_answers_section() { // defines the list of params to represents the answer $this->add_per_answer_fields($this->_form, "", question_bank::fraction_options_full(), 0); }
/** * Add question-type specific form fields. * * @param object $mform the form being built. */ protected function definition_inner($mform) { $this->add_per_answer_fields($mform, get_string('answerno', 'qtype_missingtype', '{no}'), question_bank::fraction_options_full()); }