dirroot . '/mod/quiz/editlib.php'); require_once($CFG->dirroot . '/question/category_class.php'); $PAGE->requires->yui2_lib('container'); $PAGE->requires->yui2_lib('dragdrop'); /** * Callback function called from question_list() function * (which is called from showbank()) * Displays button in form with checkboxes for each question. */ function module_specific_buttons($cmid, $cmoptions) { global $OUTPUT; if ($cmoptions->hasattempts) { $disabled = 'disabled="disabled" '; } else { $disabled = ''; } $straddtoquiz = get_string('addtoquiz', 'quiz'); $out = '\n"; return $out; } /** * Callback function called from question_list() function * (which is called from showbank()) */ function module_specific_controls($totalnumber, $recurse, $category, $cmid, $cmoptions) { global $QTYPES, $OUTPUT; $out = ''; $catcontext = get_context_instance_by_id($category->contextid); if (has_capability('moodle/question:useall', $catcontext)) { if ($cmoptions->hasattempts) { $disabled = 'disabled="disabled"'; } else { $disabled = ''; } $randomusablequestions = $QTYPES['random']->get_usable_questions_from_category($category->id, $recurse, '0'); $maxrand = count($randomusablequestions); if ($maxrand > 0) { for ($i = 1; $i <= min(10, $maxrand); $i++) { $randomcount[$i] = $i; } for ($i = 20; $i <= min(100, $maxrand); $i += 10) { $randomcount[$i] = $i; } $straddtoquiz = get_string('addtoquiz', 'quiz'); $out = '
'; $select = html_select::make($randomcount, 'randomcount', '1', false); $select->nothingvalue = ''; $select->disabled = $cmoptions->hasattempts; $out .= get_string('addrandom', 'quiz', $OUTPUT->select($select)); $out .= ''; $out .= ''; $out .= ' '; $out .= $OUTPUT->help_icon('random', get_string('random', 'quiz'), 'quiz'); } } return $out; } list($thispageurl, $contexts, $cmid, $cm, $quiz, $pagevars) = question_edit_setup('editq', true); $PAGE->set_url('/mod/quiz/edit.php', $thispageurl->params()); $PAGE->set_pagelayout('base'); $defaultcategoryobj = question_make_default_categories($contexts->all()); $defaultcategoryid = $defaultcategoryobj->id; $defaultcategorycontext = $defaultcategoryobj->contextid; $defaultcategory = $defaultcategoryid . ',' . $defaultcategorycontext; //these params are only passed from page request to request while we stay on //this page otherwise they would go in question_edit_setup $quiz_reordertool = optional_param('reordertool', 0, PARAM_BOOL); $quiz_qbanktool = optional_param('qbanktool', -1, PARAM_BOOL); if ($quiz_qbanktool > -1) { $thispageurl->param('qbanktool', $quiz_qbanktool); set_user_preference('quiz_qbanktool_open', $quiz_qbanktool); } else { $quiz_qbanktool = get_user_preferences('quiz_qbanktool_open', 0); } //will be set further down in the code $quizhasattempts = quiz_has_attempts($quiz->id); if ($quiz_reordertool != 0) { $thispageurl->param('reordertool', $quiz_reordertool); } $strquizzes = get_string('modulenameplural', 'quiz'); $strquiz = get_string('modulename', 'quiz'); $streditingquestions = get_string('editquestions', 'quiz'); //this just does not work for at least finnish, where words are conjugated: //$streditingquiz = get_string('editinga', 'moodle', $strquiz); $streditingquiz = get_string('editingquiz', 'quiz'); $strorderingquiz = get_string('orderingquiz', 'quiz'); $pagetitle = $streditingquiz; if ($quiz_reordertool) { $pagetitle = $strorderingquiz; } // Get the course object and related bits. $course = $DB->get_record('course', array('id' => $quiz->course)); if (!$course) { print_error('invalidcourseid', 'error'); } $questionbank = new quiz_question_bank_view($contexts, $thispageurl, $course, $cm); $questionbank->set_quiz_has_attempts($quizhasattempts); // Log this visit. add_to_log($cm->course, 'quiz', 'editquestions', "view.php?id=$cm->id", "$quiz->id", $cm->id); // You need mod/quiz:manage in addition to question capabilities to access this page. require_capability('mod/quiz:manage', $contexts->lowest()); if (empty($quiz->grades)) { // Construct an array to hold all the grades. $quiz->grades = quiz_get_all_question_grades($quiz); } // Process commands ============================================================ if ($quiz->shufflequestions) { // Strip page breaks before processing actions, so that re-ordering works // as expected when shuffle questions is on. $quiz->questions = quiz_repaginate($quiz->questions, 0); } // Get the list of question ids had their check-boxes ticked. $selectedquestionids = array(); $params = (array) data_submitted(); foreach ($params as $key => $value) { if (preg_match('!^s([0-9]+)$!', $key, $matches)) { $selectedquestionids[] = $matches[1]; } } if (($up = optional_param('up', false, PARAM_INT)) && confirm_sesskey()) { $quiz->questions = quiz_move_question_up($quiz->questions, $up); quiz_save_new_layout($quiz); redirect($thispageurl); } if (($down = optional_param('down', false, PARAM_INT)) && confirm_sesskey()) { $quiz->questions = quiz_move_question_down($quiz->questions, $down); quiz_save_new_layout($quiz); redirect($thispageurl); } if (optional_param('repaginate', false, PARAM_BOOL) && confirm_sesskey()) { // Re-paginate the quiz $questionsperpage = optional_param('questionsperpage', $quiz->questionsperpage, PARAM_INT); $quiz->questions = quiz_repaginate($quiz->questions, $questionsperpage ); quiz_save_new_layout($quiz); } if (($addquestion = optional_param('addquestion', 0, PARAM_INT)) && confirm_sesskey()) { /// Add a single question to the current quiz $addonpage = optional_param('addonpage', 0, PARAM_INT); quiz_add_quiz_question($addquestion, $quiz, $addonpage); quiz_update_sumgrades($quiz); quiz_delete_previews($quiz); redirect($thispageurl); } if (optional_param('add', false, PARAM_BOOL) && confirm_sesskey()) { /// Add selected questions to the current quiz $rawdata = (array) data_submitted(); foreach ($rawdata as $key => $value) { // Parse input for question ids if (preg_match('!^q([0-9]+)$!', $key, $matches)) { $key = $matches[1]; quiz_add_quiz_question($key, $quiz); } } quiz_update_sumgrades($quiz); quiz_delete_previews($quiz); redirect($thispageurl); } $qcobject = new question_category_object($pagevars['cpage'], $thispageurl, $contexts->having_one_edit_tab_cap('categories'), $defaultcategoryid, $defaultcategory, null, $contexts->having_cap('moodle/question:add')); $newrandomcategory = false; $newquestioninfo = quiz_process_randomquestion_formdata($qcobject); if ($newquestioninfo && $newquestioninfo != 'cancelled') { $newrandomcategory = $newquestioninfo->newrandomcategory; if (!$newrandomcategory) { print_error('cannotcreatecategory'); } else { add_to_log($quiz->course, 'quiz', 'addcategory', "view.php?id=$cm->id", $newrandomcategory, $cm->id); } } if ((optional_param('addrandom', false, PARAM_BOOL) || $newrandomcategory) && confirm_sesskey()) { /// Add random questions to the quiz $recurse = optional_param('recurse', 0, PARAM_BOOL); $addonpage = optional_param('addonpage', 0, PARAM_INT); if ($newrandomcategory) { $categoryid = $newrandomcategory; $randomcount = optional_param('randomcount', 1, PARAM_INT); } else { $categoryid = required_param('categoryid', PARAM_INT); $randomcount = required_param('randomcount', PARAM_INT); } // load category $category = $DB->get_record('question_categories', array('id' => $categoryid)); if (!$category) { print_error('invalidcategoryid', 'error'); } $catcontext = get_context_instance_by_id($category->contextid); require_capability('moodle/question:useall', $catcontext); $category->name = $category->name; // Find existing random questions in this category that are // not used by any quiz. if ($existingquestions = $DB->get_records_sql( "SELECT q.id,q.qtype FROM {question} q WHERE qtype = '" . RANDOM . "' AND category = ? AND " . $DB->sql_compare_text('questiontext') . " = ? AND NOT EXISTS (SELECT * FROM {quiz_question_instances} WHERE question = q.id) ORDER BY id", array($category->id, $recurse))) { // Take as many of these as needed. while (($existingquestion = array_shift($existingquestions)) && $randomcount > 0) { quiz_add_quiz_question($existingquestion->id, $quiz, $addonpage); $randomcount--; } } // If more are needed, create them. if ($randomcount > 0) { $form->questiontext = $recurse; // we use the questiontext field // to store the info on whether to include // questions in subcategories $form->questiontextformat = 0; $form->image = ''; $form->defaultgrade = 1; $form->hidden = 1; for ($i = 0; $i < $randomcount; $i++) { $form->category = $category->id . ',' . $category->contextid; $form->stamp = make_unique_id_code(); // Set the unique //code (not to be changed) $question = new stdClass; $question->qtype = RANDOM; $question = $QTYPES[RANDOM]->save_question($question, $form, $course); if(!isset($question->id)) { print_error('cannotinsertrandomquestion', 'quiz'); } quiz_add_quiz_question($question->id, $quiz, $addonpage); } } quiz_update_sumgrades($quiz); quiz_delete_previews($quiz); redirect($thispageurl); } if (optional_param('addnewpagesafterselected', null, PARAM_CLEAN) && !empty($selectedquestionids) && confirm_sesskey()) { foreach ($selectedquestionids as $questionid) { $quiz->questions = quiz_add_page_break_after($quiz->questions, $questionid); } quiz_save_new_layout($quiz); redirect($thispageurl); } $addpage = optional_param('addpage', false, PARAM_INT); if ($addpage !== false && confirm_sesskey()) { $quiz->questions = quiz_add_page_break_at($quiz->questions, $addpage); quiz_save_new_layout($quiz); redirect($thispageurl); } $deleteemptypage = optional_param('deleteemptypage', false, PARAM_INT); if (($deleteemptypage !== false) && confirm_sesskey()) { $quiz->questions = quiz_delete_empty_page($quiz->questions, $deleteemptypage); quiz_save_new_layout($quiz); redirect($thispageurl); } $remove = optional_param('remove', false, PARAM_INT); if (($remove = optional_param('remove', false, PARAM_INT)) && confirm_sesskey()) { quiz_remove_question($quiz, $remove); quiz_update_sumgrades($quiz); quiz_delete_previews($quiz); redirect($thispageurl); } if (optional_param('quizdeleteselected', false, PARAM_BOOL) && !empty($selectedquestionids) && confirm_sesskey()) { foreach ($selectedquestionids as $questionid) { quiz_remove_question($quiz, $questionid); } quiz_update_sumgrades($quiz); quiz_delete_previews($quiz); redirect($thispageurl); } if (optional_param('savechanges', false, PARAM_BOOL) && confirm_sesskey()) { $oldquestions = explode(',', $quiz->questions); // the questions in the old order $questions = array(); // for questions in the new order $rawdata = (array) data_submitted(); $moveonpagequestions = array(); $moveselectedonpage = optional_param('moveselectedonpagetop', 0, PARAM_INT); if (!$moveselectedonpage) { $moveselectedonpage = optional_param('moveselectedonpagebottom', 0, PARAM_INT); } foreach ($rawdata as $key => $value) { if (preg_match('!^g([0-9]+)$!', $key, $matches)) { /// Parse input for question -> grades $questionid = $matches[1]; $quiz->grades[$questionid] = clean_param($value, PARAM_FLOAT); quiz_update_question_instance($quiz->grades[$questionid], $questionid, $quiz->id); quiz_delete_previews($quiz); quiz_update_sumgrades($quiz); } else if (preg_match('!^o(pg)?([0-9]+)$!', $key, $matches)) { /// Parse input for ordering info $questionid = $matches[2]; // Make sure two questions don't overwrite each other. If we get a second // question with the same position, shift the second one along to the next gap. $value = clean_param($value, PARAM_INTEGER); while (array_key_exists($value, $questions)) { $value++; } if ($matches[1]) { // This is a page-break entry. $questions[$value] = 0; } else { $questions[$value] = $questionid; } } } // If ordering info was given, reorder the questions if ($questions) { ksort($questions); $questions[] = 0; $quiz->questions = implode(',', $questions); quiz_save_new_layout($quiz); quiz_delete_previews($quiz); } //get a list of questions to move, later to be added in the appropriate //place in the string if ($moveselectedonpage) { $questions = explode(',', $quiz->questions); $newquestions = array(); //remove the questions from their original positions first foreach ($questions as $questionid) { if (!in_array($questionid, $selectedquestionids)) { $newquestions[] = $questionid; } } $questions = $newquestions; //move to the end of the selected page $pagebreakpositions = array_keys($questions, 0); $numpages = count($pagebreakpositions); // Ensure the target page number is in range. $moveselectedonpage = max(1, min($moveselectedonpage, $pagebreakpositions)); $moveselectedpos = $pagebreakpositions[$moveselectedonpage - 1]; array_splice($questions, $moveselectedpos, 0, $selectedquestionids); $quiz->questions = implode(',', $questions); quiz_save_new_layout($quiz); quiz_delete_previews($quiz); } // If rescaling is required save the new maximum $maxgrade = optional_param('maxgrade', -1, PARAM_FLOAT); if ($maxgrade >= 0) { quiz_set_grade($maxgrade, $quiz); } redirect($thispageurl); } $questionbank->process_actions($thispageurl, $cm); // End of process commands ===================================================== // Print the header. $questionbankmanagement = ''. get_string('questionbankmanagement', 'quiz').' '; $PAGE->navbar->add($pagetitle); $PAGE->requires->skip_link_to('questionbank', get_string('skipto', 'access', get_string('questionbank', 'question'))); $PAGE->requires->skip_link_to('quizcontentsblock', get_string('skipto', 'access', get_string('questionsinthisquiz', 'quiz'))); $PAGE->set_title($pagetitle); $PAGE->set_button($questionbankmanagement); echo $OUTPUT->header(); // Initialise the JavaScript. $quizeditconfig = new stdClass; $quizeditconfig->url = $thispageurl->out(true, array('qbanktool' => '0')); $quizeditconfig->dialoglisteners = array(); $numberoflisteners = max(quiz_number_of_pages($quiz->questions), 1); for ($pageiter = 1; $pageiter <= $numberoflisteners; $pageiter++) { $quizeditconfig->dialoglisteners[] = 'addrandomdialoglaunch_' . $pageiter; } $PAGE->requires->data_for_js('quiz_edit_config', $quizeditconfig); $PAGE->requires->js('/mod/quiz/edit.js'); // Print the tabs. $currenttab = 'edit'; $mode = 'editq'; if ($quiz_reordertool) { $mode = 'reorder'; } include('tabs.php'); if ($quiz_qbanktool) { $bankclass = ''; $quizcontentsclass = ''; } else { $bankclass = 'collapsed '; $quizcontentsclass = 'quizwhenbankcollapsed'; } echo '
'; echo '

'; echo get_string('questionbankcontents', 'quiz') . ' [' . get_string('show'). '] [' . get_string('hide'). ']'; echo '

'; echo ''; echo '
'; echo '
'; echo '
'; $questionbank->display('editq', $pagevars['qpage'], $pagevars['qperpage'], $pagevars['qsortorder'], $pagevars['qsortorderdecoded'], $pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'], $pagevars['showquestiontext']); echo '
'; echo '
'; echo '
'; echo '
'; echo '
'; if ($quiz->shufflequestions) { $repaginatingdisabledhtml = 'disabled="disabled"'; $repaginatingdisabled = true; $quiz->questions = quiz_repaginate($quiz->questions, $quiz->questionsperpage); } else { $repaginatingdisabledhtml = ''; $repaginatingdisabled = false; } if ($quiz_reordertool) { echo '
'; echo '
'; } echo $OUTPUT->heading($pagetitle.": ".$quiz->name, 2); echo $OUTPUT->help_icon('editconcepts', get_string('basicideasofquiz', 'quiz'), 'quiz', true); quiz_print_status_bar($quiz); $tabindex = 0; if (!$quiz_reordertool) { quiz_print_grading_form($quiz, $thispageurl, $tabindex); } $notifystrings = array(); if ($quizhasattempts) { $reviewlink = '' . quiz_num_attempt_summary($quiz, $cm) . ''; $notifystrings[] = get_string('cannoteditafterattempts', 'quiz', $reviewlink); } if ($quiz->shufflequestions) { $updateurl = new moodle_url("$CFG->wwwroot/course/mod.php", array('return' => 'true', 'update' => $quiz->cmid, 'sesskey' => sesskey())); $updatelink = '' . get_string('updatethis', '', get_string('modulename', 'quiz')) . ''; $notifystrings[] = get_string('shufflequestionsselected', 'quiz', $updatelink); } if (!empty($notifystrings)) { echo $OUTPUT->box('

' . implode('

', $notifystrings) . '

', 'statusdisplay'); } if ($quiz_reordertool) { $perpage= array(); $perpage[0] = get_string('allinone', 'quiz'); for ($i = 1; $i <= 50; ++$i) { $perpage[$i] = $i; } $gostring = get_string('go'); echo '
'; echo get_string('repaginatecommand', 'quiz'); echo '
'; echo '
'; echo '
'; echo html_writer::input_hidden_params($thispageurl); echo ''; //YUI does not submit the value of the submit button so //we need to add the value: echo ''; $select = html_select::make($perpage, 'questionsperpage', $quiz->questionsperpage, false); $select->nothingvalue = ''; $select->disabled = $repaginatingdisabledhtml; print_string('repaginate', 'quiz', $OUTPUT->select($select)); echo '
'; echo ' '; echo '
'; } echo '
'; quiz_print_question_list($quiz, $thispageurl, true, $quiz_reordertool, $quiz_qbanktool, $quizhasattempts); echo '
'; // Close
: echo '
'; if (!$quiz_reordertool) { // display category adding UI ?>
name); ?>
display_randomquestion_user_interface(); ?>
footer(); ?>