/** * Retrieves the lesson page type manager object * * If the object hasn't yet been created it is created here. * * @staticvar lesson_page_type_manager $pagetypemanager * @param lesson $lesson * @return lesson_page_type_manager */ public static function get(lesson $lesson) { static $pagetypemanager; if (!$pagetypemanager instanceof lesson_page_type_manager) { $pagetypemanager = new lesson_page_type_manager(); $pagetypemanager->load_lesson_types($lesson); } return $pagetypemanager; }
/** * Returns HTML to display action links for a page * * @param lesson_page $page * @param bool $printmove * @param bool $printaddpage * @return string */ public function page_action_links(lesson_page $page, $printmove, $printaddpage = false) { global $CFG; $actions = array(); if ($printmove) { $printmovehtml = new moodle_url('/mod/lesson/lesson.php', array('id' => $this->page->cm->id, 'action' => 'move', 'pageid' => $page->id, 'sesskey' => sesskey())); $actions[] = html_writer::link($printmovehtml, '<img src="' . $this->output->pix_url('t/move') . '" class="iconsmall" alt="' . get_string('move') . '" />'); } $url = new moodle_url('/mod/lesson/editpage.php', array('id' => $this->page->cm->id, 'pageid' => $page->id, 'edit' => 1)); $actions[] = html_writer::link($url, '<img src="' . $this->output->pix_url('t/edit') . '" class="iconsmall" alt="' . get_string('update') . '" />'); $url = new moodle_url('/mod/lesson/view.php', array('id' => $this->page->cm->id, 'pageid' => $page->id)); $actions[] = html_writer::link($url, '<img src="' . $this->output->pix_url('t/preview') . '" class="iconsmall" alt="' . get_string('preview') . '" />'); $url = new moodle_url('/mod/lesson/lesson.php', array('id' => $this->page->cm->id, 'action' => 'confirmdelete', 'pageid' => $page->id, 'sesskey' => sesskey())); $actions[] = html_writer::link($url, '<img src="' . $this->output->pix_url('t/delete') . '" class="iconsmall" alt="' . get_string('delete') . '" />'); if ($printaddpage) { $options = array(); $manager = lesson_page_type_manager::get($page->lesson); $links = $manager->get_add_page_type_links($page->id); foreach ($links as $link) { $options[$link['type']] = $link['name']; } $options[0] = get_string('question', 'lesson'); $addpageurl = new moodle_url('/mod/lesson/editpage.php', array('id' => $this->page->cm->id, 'pageid' => $page->id, 'sesskey' => sesskey())); $addpageselect = new single_select($addpageurl, 'qtype', $options, null, array('' => get_string('addanewpage', 'lesson') . '...'), 'addpageafter' . $page->id); $addpageselector = $this->output->render($addpageselect); } if (isset($addpageselector)) { $actions[] = $addpageselector; } return implode(' ', $actions); }
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST); $lesson = new lesson($DB->get_record('lesson', array('id' => $cm->instance), '*', MUST_EXIST)); require_login($course, false, $cm); $context = context_module::instance($cm->id); require_capability('mod/lesson:edit', $context); $PAGE->set_url('/mod/lesson/editpage.php', array('pageid' => $pageid, 'id' => $id, 'qtype' => $qtype)); $PAGE->set_pagelayout('admin'); if ($edit) { $editpage = lesson_page::load($pageid, $lesson); $qtype = $editpage->qtype; $edit = true; } else { $edit = false; } $jumpto = lesson_page::get_jumptooptions($pageid, $lesson); $manager = lesson_page_type_manager::get($lesson); $editoroptions = array('noclean' => true, 'maxfiles' => EDITOR_UNLIMITED_FILES, 'maxbytes' => $CFG->maxbytes); // If the previous page was the Question type selection form, this form // will have a different name (e.g. _qf__lesson_add_page_form_selection // versus _qf__lesson_add_page_form_multichoice). This causes confusion // in moodleform::_process_submission because the array key check doesn't // tie up with the current form name, which in turn means the "submitted" // check ends up evaluating as false, thus it's not possible to check whether // the Question type selection was cancelled. For this reason, a dummy form // is created here solely to check whether the selection was cancelled. if ($qtype) { $mformdummy = $manager->get_page_form(0, array('editoroptions' => $editoroptions, 'jumpto' => $jumpto, 'lesson' => $lesson, 'edit' => $edit, 'maxbytes' => $PAGE->course->maxbytes, 'returnto' => $returnto)); if ($mformdummy->is_cancelled()) { redirect($returnto); exit; }
public function __construct($arg1, $arg2) { $this->manager = lesson_page_type_manager::get($arg2['lesson']); parent::__construct($arg1, $arg2); }
/** * Given some question info and some data about the the answers * this function parses, organises and saves the question * * This is only used when IMPORTING questions and is only called * from format.php * Lifted from mod/quiz/lib.php - * 1. all reference to oldanswers removed * 2. all reference to quiz_multichoice table removed * 3. In SHORTANSWER questions usecase is store in the qoption field * 4. In NUMERIC questions store the range as two answers * 5. TRUEFALSE options are ignored * 6. For MULTICHOICE questions with more than one answer the qoption field is true * * @param opject $question Contains question data like question, type and answers. * @return object Returns $result->error or $result->notice. **/ function lesson_save_question_options($question, $lesson) { global $DB; // These lines are required to ensure that all page types have // been loaded for the following switch if (!($lesson instanceof lesson)) { $lesson = new lesson($lesson); } $manager = lesson_page_type_manager::get($lesson); $timenow = time(); $result = new stdClass(); switch ($question->qtype) { case LESSON_PAGE_SHORTANSWER: $answers = array(); $maxfraction = -1; // Insert all the new answers foreach ($question->answer as $key => $dataanswer) { if ($dataanswer != "") { $answer = new stdClass; $answer->lessonid = $question->lessonid; $answer->pageid = $question->id; if ($question->fraction[$key] >=0.5) { $answer->jumpto = LESSON_NEXTPAGE; } $answer->timecreated = $timenow; $answer->grade = $question->fraction[$key] * 100; $answer->answer = $dataanswer; $answer->response = $question->feedback[$key]; $answer->id = $DB->insert_record("lesson_answers", $answer); $answers[] = $answer->id; if ($question->fraction[$key] > $maxfraction) { $maxfraction = $question->fraction[$key]; } } } /// Perform sanity checks on fractional grades if ($maxfraction != 1) { $maxfraction = $maxfraction * 100; $result->notice = get_string("fractionsnomax", "quiz", $maxfraction); return $result; } break; case LESSON_PAGE_NUMERICAL: // Note similarities to SHORTANSWER $answers = array(); $maxfraction = -1; // for each answer store the pair of min and max values even if they are the same foreach ($question->answer as $key => $dataanswer) { if ($dataanswer != "") { $answer = new stdClass; $answer->lessonid = $question->lessonid; $answer->pageid = $question->id; $answer->jumpto = LESSON_NEXTPAGE; $answer->timecreated = $timenow; $answer->grade = $question->fraction[$key] * 100; $min = $question->answer[$key] - $question->tolerance[$key]; $max = $question->answer[$key] + $question->tolerance[$key]; $answer->answer = $min.":".$max; // $answer->answer = $question->min[$key].":".$question->max[$key]; original line for min/max $answer->response = $question->feedback[$key]; $answer->id = $DB->insert_record("lesson_answers", $answer); $answers[] = $answer->id; if ($question->fraction[$key] > $maxfraction) { $maxfraction = $question->fraction[$key]; } } } /// Perform sanity checks on fractional grades if ($maxfraction != 1) { $maxfraction = $maxfraction * 100; $result->notice = get_string("fractionsnomax", "quiz", $maxfraction); return $result; } break; case LESSON_PAGE_TRUEFALSE: // the truth $answer->lessonid = $question->lessonid; $answer->pageid = $question->id; $answer->timecreated = $timenow; $answer->answer = get_string("true", "quiz"); $answer->grade = $question->answer * 100; if ($answer->grade > 50 ) { $answer->jumpto = LESSON_NEXTPAGE; } if (isset($question->feedbacktrue)) { $answer->response = $question->feedbacktrue; } $DB->insert_record("lesson_answers", $answer); // the lie $answer = new stdClass; $answer->lessonid = $question->lessonid; $answer->pageid = $question->id; $answer->timecreated = $timenow; $answer->answer = get_string("false", "quiz"); $answer->grade = (1 - (int)$question->answer) * 100; if ($answer->grade > 50 ) { $answer->jumpto = LESSON_NEXTPAGE; } if (isset($question->feedbackfalse)) { $answer->response = $question->feedbackfalse; } $DB->insert_record("lesson_answers", $answer); break; case LESSON_PAGE_MULTICHOICE: $totalfraction = 0; $maxfraction = -1; $answers = array(); // Insert all the new answers foreach ($question->answer as $key => $dataanswer) { if ($dataanswer != "") { $answer = new stdClass; $answer->lessonid = $question->lessonid; $answer->pageid = $question->id; $answer->timecreated = $timenow; $answer->grade = $question->fraction[$key] * 100; // changed some defaults /* Original Code if ($answer->grade > 50 ) { $answer->jumpto = LESSON_NEXTPAGE; } Replaced with: */ if ($answer->grade > 50 ) { $answer->jumpto = LESSON_NEXTPAGE; $answer->score = 1; } // end Replace $answer->answer = $dataanswer; $answer->response = $question->feedback[$key]; $answer->id = $DB->insert_record("lesson_answers", $answer); // for Sanity checks if ($question->fraction[$key] > 0) { $totalfraction += $question->fraction[$key]; } if ($question->fraction[$key] > $maxfraction) { $maxfraction = $question->fraction[$key]; } } } /// Perform sanity checks on fractional grades if ($question->single) { if ($maxfraction != 1) { $maxfraction = $maxfraction * 100; $result->notice = get_string("fractionsnomax", "quiz", $maxfraction); return $result; } } else { $totalfraction = round($totalfraction,2); if ($totalfraction != 1) { $totalfraction = $totalfraction * 100; $result->notice = get_string("fractionsaddwrong", "quiz", $totalfraction); return $result; } } break; case LESSON_PAGE_MATCHING: $subquestions = array(); $defaultanswer = new stdClass; $defaultanswer->lessonid = $question->lessonid; $defaultanswer->pageid = $question->id; $defaultanswer->timecreated = $timenow; $defaultanswer->grade = 0; // The first answer should always be the correct answer $correctanswer = clone($defaultanswer); $correctanswer->answer = get_string('thatsthecorrectanswer', 'lesson'); $DB->insert_record("lesson_answers", $correctanswer); // The second answer should always be the wrong answer $wronganswer = clone($defaultanswer); $wronganswer->answer = get_string('thatsthewronganswer', 'lesson'); $DB->insert_record("lesson_answers", $wronganswer); $i = 0; // Insert all the new question+answer pairs foreach ($question->subquestions as $key => $questiontext) { $answertext = $question->subanswers[$key]; if (!empty($questiontext) and !empty($answertext)) { $answer = clone($defaultanswer); $answer->answer = $questiontext; $answer->response = $answertext; if ($i == 0) { // first answer contains the correct answer jump $answer->jumpto = LESSON_NEXTPAGE; } $subquestions[] = $DB->insert_record("lesson_answers", $answer); $i++; } } if (count($subquestions) < 3) { $result->notice = get_string("notenoughsubquestions", "quiz"); return $result; } break; default: $result->error = "Unsupported question type ($question->qtype)!"; return $result; } return true; }
/** * Given some question info and some data about the the answers * this function parses, organises and saves the question * * This is only used when IMPORTING questions and is only called * from format.php * Lifted from mod/quiz/lib.php - * 1. all reference to oldanswers removed * 2. all reference to quiz_multichoice table removed * 3. In shortanswer questions usecase is store in the qoption field * 4. In numeric questions store the range as two answers * 5. truefalse options are ignored * 6. For multichoice questions with more than one answer the qoption field is true * * @param object $question Contains question data like question, type and answers. * @param object $lesson * @param int $contextid * @return object Returns $result->error or $result->notice. **/ function lesson_save_question_options($question, $lesson, $contextid) { global $DB; // These lines are required to ensure that all page types have // been loaded for the following switch if (!$lesson instanceof lesson) { $lesson = new lesson($lesson); } $manager = lesson_page_type_manager::get($lesson); $timenow = time(); $result = new stdClass(); // Default answer to avoid code duplication. $defaultanswer = new stdClass(); $defaultanswer->lessonid = $question->lessonid; $defaultanswer->pageid = $question->id; $defaultanswer->timecreated = $timenow; $defaultanswer->answerformat = FORMAT_HTML; $defaultanswer->jumpto = LESSON_THISPAGE; $defaultanswer->grade = 0; $defaultanswer->score = 0; switch ($question->qtype) { case LESSON_PAGE_SHORTANSWER: $answers = array(); $maxfraction = -1; // Insert all the new answers foreach ($question->answer as $key => $dataanswer) { if ($dataanswer != "") { $answer = clone $defaultanswer; if ($question->fraction[$key] >= 0.5) { $answer->jumpto = LESSON_NEXTPAGE; $answer->score = 1; } $answer->grade = round($question->fraction[$key] * 100); $answer->answer = $dataanswer; $answer->response = $question->feedback[$key]['text']; $answer->responseformat = $question->feedback[$key]['format']; $answer->id = $DB->insert_record("lesson_answers", $answer); lesson_import_question_files('response', $question->feedback[$key], $answer, $contextid); $answers[] = $answer->id; if ($question->fraction[$key] > $maxfraction) { $maxfraction = $question->fraction[$key]; } } } /// Perform sanity checks on fractional grades if ($maxfraction != 1) { $maxfraction = $maxfraction * 100; $result->notice = get_string("fractionsnomax", "lesson", $maxfraction); return $result; } break; case LESSON_PAGE_NUMERICAL: // Note similarities to shortanswer. $answers = array(); $maxfraction = -1; // for each answer store the pair of min and max values even if they are the same foreach ($question->answer as $key => $dataanswer) { if ($dataanswer != "") { $answer = clone $defaultanswer; if ($question->fraction[$key] >= 0.5) { $answer->jumpto = LESSON_NEXTPAGE; $answer->score = 1; } $answer->grade = round($question->fraction[$key] * 100); $min = $question->answer[$key] - $question->tolerance[$key]; $max = $question->answer[$key] + $question->tolerance[$key]; $answer->answer = $min . ":" . $max; $answer->response = $question->feedback[$key]['text']; $answer->responseformat = $question->feedback[$key]['format']; $answer->id = $DB->insert_record("lesson_answers", $answer); lesson_import_question_files('response', $question->feedback[$key], $answer, $contextid); $answers[] = $answer->id; if ($question->fraction[$key] > $maxfraction) { $maxfraction = $question->fraction[$key]; } } } /// Perform sanity checks on fractional grades if ($maxfraction != 1) { $maxfraction = $maxfraction * 100; $result->notice = get_string("fractionsnomax", "lesson", $maxfraction); return $result; } break; case LESSON_PAGE_TRUEFALSE: // the truth $answer = clone $defaultanswer; $answer->answer = get_string("true", "lesson"); $answer->grade = $question->correctanswer * 100; if ($answer->grade > 50) { $answer->jumpto = LESSON_NEXTPAGE; $answer->score = 1; } if (isset($question->feedbacktrue)) { $answer->response = $question->feedbacktrue['text']; $answer->responseformat = $question->feedbacktrue['format']; } $answer->id = $DB->insert_record("lesson_answers", $answer); lesson_import_question_files('response', $question->feedbacktrue, $answer, $contextid); // the lie $answer = clone $defaultanswer; $answer->answer = get_string("false", "lesson"); $answer->grade = (1 - (int) $question->correctanswer) * 100; if ($answer->grade > 50) { $answer->jumpto = LESSON_NEXTPAGE; $answer->score = 1; } if (isset($question->feedbackfalse)) { $answer->response = $question->feedbackfalse['text']; $answer->responseformat = $question->feedbackfalse['format']; } $answer->id = $DB->insert_record("lesson_answers", $answer); lesson_import_question_files('response', $question->feedbackfalse, $answer, $contextid); break; case LESSON_PAGE_MULTICHOICE: $totalfraction = 0; $maxfraction = -1; $answers = array(); // Insert all the new answers foreach ($question->answer as $key => $dataanswer) { if ($dataanswer != "") { $answer = clone $defaultanswer; $answer->grade = round($question->fraction[$key] * 100); if ($question->single) { if ($answer->grade > 50) { $answer->jumpto = LESSON_NEXTPAGE; $answer->score = 1; } } else { // If multi answer allowed, any answer with fraction > 0 is considered correct. if ($question->fraction[$key] > 0) { $answer->jumpto = LESSON_NEXTPAGE; $answer->score = 1; } } $answer->answer = $dataanswer['text']; $answer->answerformat = $dataanswer['format']; $answer->response = $question->feedback[$key]['text']; $answer->responseformat = $question->feedback[$key]['format']; $answer->id = $DB->insert_record("lesson_answers", $answer); lesson_import_question_files('answer', $dataanswer, $answer, $contextid); lesson_import_question_files('response', $question->feedback[$key], $answer, $contextid); // for Sanity checks if ($question->fraction[$key] > 0) { $totalfraction += $question->fraction[$key]; } if ($question->fraction[$key] > $maxfraction) { $maxfraction = $question->fraction[$key]; } } } /// Perform sanity checks on fractional grades if ($question->single) { if ($maxfraction != 1) { $maxfraction = $maxfraction * 100; $result->notice = get_string("fractionsnomax", "lesson", $maxfraction); return $result; } } else { $totalfraction = round($totalfraction, 2); if ($totalfraction != 1) { $totalfraction = $totalfraction * 100; $result->notice = get_string("fractionsaddwrong", "lesson", $totalfraction); return $result; } } break; case LESSON_PAGE_MATCHING: $subquestions = array(); // The first answer should always be the correct answer $correctanswer = clone $defaultanswer; $correctanswer->answer = get_string('thatsthecorrectanswer', 'lesson'); $correctanswer->jumpto = LESSON_NEXTPAGE; $correctanswer->score = 1; $DB->insert_record("lesson_answers", $correctanswer); // The second answer should always be the wrong answer $wronganswer = clone $defaultanswer; $wronganswer->answer = get_string('thatsthewronganswer', 'lesson'); $DB->insert_record("lesson_answers", $wronganswer); $i = 0; // Insert all the new question+answer pairs foreach ($question->subquestions as $key => $questiontext) { $answertext = $question->subanswers[$key]; if (!empty($questiontext) and !empty($answertext)) { $answer = clone $defaultanswer; $answer->answer = $questiontext['text']; $answer->answerformat = $questiontext['format']; $answer->response = $answertext; if ($i == 0) { // first answer contains the correct answer jump $answer->jumpto = LESSON_NEXTPAGE; } $answer->id = $DB->insert_record("lesson_answers", $answer); lesson_import_question_files('answer', $questiontext, $answer, $contextid); $subquestions[] = $answer->id; $i++; } } if (count($subquestions) < 3) { $result->notice = get_string("notenoughsubquestions", "lesson"); return $result; } break; case LESSON_PAGE_ESSAY: $answer = new stdClass(); $answer->lessonid = $question->lessonid; $answer->pageid = $question->id; $answer->timecreated = $timenow; $answer->answer = null; $answer->answerformat = FORMAT_MOODLE; $answer->grade = 0; $answer->score = 1; $answer->jumpto = LESSON_NEXTPAGE; $answer->response = null; $answer->responseformat = FORMAT_MOODLE; $answer->id = $DB->insert_record("lesson_answers", $answer); break; default: $result->error = "Unsupported question type ({$question->qtype})!"; return $result; } return true; }