From 16fa272e29cb205de97b2c620afd637b8c45ef24 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Thu, 2 Oct 2014 23:15:59 +0100 Subject: [PATCH] MDL-47132 quiz: move the remains of editlib.php to locallib.php --- mod/quiz/addrandom.php | 5 +- mod/quiz/edit.php | 5 +- mod/quiz/edit_rest.php | 3 +- mod/quiz/editlib.php | 202 ------------------ mod/quiz/locallib.php | 171 ++++++++++++++- mod/quiz/questionbank.ajax.php | 6 +- .../attempt_walkthrough_from_csv_test.php | 1 - mod/quiz/tests/attempt_walkthrough_test.php | 1 - mod/quiz/tests/events_test.php | 1 - mod/quiz/tests/lib_test.php | 3 - mod/quiz/tests/repaginate_test.php | 1 - mod/quiz/tests/structure_test.php | 1 - mod/quiz/upgrade.txt | 4 +- 13 files changed, 182 insertions(+), 222 deletions(-) delete mode 100644 mod/quiz/editlib.php diff --git a/mod/quiz/addrandom.php b/mod/quiz/addrandom.php index 3f80896807321..658ecb86cf2d3 100644 --- a/mod/quiz/addrandom.php +++ b/mod/quiz/addrandom.php @@ -24,9 +24,10 @@ */ -require_once('../../config.php'); -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); +require_once(__DIR__ . '/../../config.php'); +require_once($CFG->dirroot . '/mod/quiz/locallib.php'); require_once($CFG->dirroot . '/mod/quiz/addrandomform.php'); +require_once($CFG->dirroot . '/question/editlib.php'); require_once($CFG->dirroot . '/question/category_class.php'); list($thispageurl, $contexts, $cmid, $cm, $quiz, $pagevars) = diff --git a/mod/quiz/edit.php b/mod/quiz/edit.php index 1c0e763ca45c8..d7998e57fb9f5 100644 --- a/mod/quiz/edit.php +++ b/mod/quiz/edit.php @@ -41,9 +41,10 @@ */ -require_once('../../config.php'); -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); +require_once(__DIR__ . '/../../config.php'); +require_once($CFG->dirroot . '/mod/quiz/locallib.php'); require_once($CFG->dirroot . '/mod/quiz/addrandomform.php'); +require_once($CFG->dirroot . '/question/editlib.php'); require_once($CFG->dirroot . '/question/category_class.php'); // These params are only passed from page request to request while we stay on diff --git a/mod/quiz/edit_rest.php b/mod/quiz/edit_rest.php index 8d5e933ecafce..55b09fa74f323 100644 --- a/mod/quiz/edit_rest.php +++ b/mod/quiz/edit_rest.php @@ -27,8 +27,7 @@ } require_once(__DIR__ . '/../../config.php'); -require_once($CFG->dirroot . '/course/lib.php'); -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); +require_once($CFG->dirroot . '/mod/quiz/locallib.php'); // Initialise ALL the incoming parameters here, up front. $quizid = required_param('quizid', PARAM_INT); diff --git a/mod/quiz/editlib.php b/mod/quiz/editlib.php deleted file mode 100644 index 0652481778d1b..0000000000000 --- a/mod/quiz/editlib.php +++ /dev/null @@ -1,202 +0,0 @@ -. - - -/** - * This contains functions that are called from within the quiz module only - * Functions that are also called by core Moodle are in {@link lib.php} - * This script also loads the code in {@link questionlib.php} which holds - * the module-indpendent code for handling questions and which in turn - * initialises all the questiontype classes. - * - * @package mod_quiz - * @copyright 1999 onwards Martin Dougiamas and others {@link http://moodle.com} - * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later - */ - - -defined('MOODLE_INTERNAL') || die(); - -require_once($CFG->dirroot . '/mod/quiz/locallib.php'); - -/** - * Verify that the question exists, and the user has permission to use it. - * Does not return. Throws an exception if the question cannot be used. - * @param int $questionid The id of the question. - */ -function quiz_require_question_use($questionid) { - global $DB; - $question = $DB->get_record('question', array('id' => $questionid), '*', MUST_EXIST); - question_require_capability_on($question, 'use'); -} - -/** - * Verify that the question exists, and the user has permission to use it. - * @param object $quiz the quiz settings. - * @param int $slot which question in the quiz to test. - * @return bool whether the user can use this question. - */ -function quiz_has_question_use($quiz, $slot) { - global $DB; - $question = $DB->get_record_sql(" - SELECT q.* - FROM {quiz_slots} slot - JOIN {question} q ON q.id = slot.questionid - WHERE slot.quizid = ? AND slot.slot = ?", array($quiz->id, $slot)); - if (!$question) { - return false; - } - return question_has_capability_on($question, 'use'); -} - -/** - * Add a question to a quiz - * - * Adds a question to a quiz by updating $quiz as well as the - * quiz and quiz_slots tables. It also adds a page break if required. - * @param int $questionid The id of the question to be added - * @param object $quiz The extended quiz object as used by edit.php - * This is updated by this function - * @param int $page Which page in quiz to add the question on. If 0 (default), - * add at the end - * @param float $maxmark The maximum mark to set for this question. (Optional, - * defaults to question.defaultmark. - * @return bool false if the question was already in the quiz - */ -function quiz_add_quiz_question($questionid, $quiz, $page = 0, $maxmark = null) { - global $DB; - $slots = $DB->get_records('quiz_slots', array('quizid' => $quiz->id), - 'slot', 'questionid, slot, page, id'); - if (array_key_exists($questionid, $slots)) { - return false; - } - - $trans = $DB->start_delegated_transaction(); - - $maxpage = 1; - $numonlastpage = 0; - foreach ($slots as $slot) { - if ($slot->page > $maxpage) { - $maxpage = $slot->page; - $numonlastpage = 1; - } else { - $numonlastpage += 1; - } - } - - // Add the new question instance. - $slot = new stdClass(); - $slot->quizid = $quiz->id; - $slot->questionid = $questionid; - - if ($maxmark !== null) { - $slot->maxmark = $maxmark; - } else { - $slot->maxmark = $DB->get_field('question', 'defaultmark', array('id' => $questionid)); - } - - if (is_int($page) && $page >= 1) { - // Adding on a given page. - $lastslotbefore = 0; - foreach (array_reverse($slots) as $otherslot) { - if ($otherslot->page > $page) { - $DB->set_field('quiz_slots', 'slot', $otherslot->slot + 1, array('id' => $otherslot->id)); - } else { - $lastslotbefore = $otherslot->slot; - break; - } - } - $slot->slot = $lastslotbefore + 1; - $slot->page = min($page, $maxpage + 1); - - } else { - $lastslot = end($slots); - if ($lastslot) { - $slot->slot = $lastslot->slot + 1; - } else { - $slot->slot = 1; - } - if ($quiz->questionsperpage && $numonlastpage >= $quiz->questionsperpage) { - $slot->page = $maxpage + 1; - } else { - $slot->page = $maxpage; - } - } - - $DB->insert_record('quiz_slots', $slot); - $trans->allow_commit(); -} - -/** - * Add a random question to the quiz at a given point. - * @param object $quiz the quiz settings. - * @param int $addonpage the page on which to add the question. - * @param int $categoryid the question category to add the question from. - * @param int $number the number of random questions to add. - * @param bool $includesubcategories whether to include questoins from subcategories. - */ -function quiz_add_random_questions($quiz, $addonpage, $categoryid, $number, - $includesubcategories) { - global $DB; - - $category = $DB->get_record('question_categories', array('id' => $categoryid)); - if (!$category) { - print_error('invalidcategoryid', 'error'); - } - - $catcontext = context::instance_by_id($category->contextid); - require_capability('moodle/question:useall', $catcontext); - - // 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_slots} - WHERE questionid = q.id) - ORDER BY id", array($category->id, ($includesubcategories ? '1' : '0')))) { - // Take as many of these as needed. - while (($existingquestion = array_shift($existingquestions)) && $number > 0) { - quiz_add_quiz_question($existingquestion->id, $quiz, $addonpage); - $number -= 1; - } - } - - if ($number <= 0) { - return; - } - - // More random questions are needed, create them. - for ($i = 0; $i < $number; $i += 1) { - $form = new stdClass(); - $form->questiontext = array('text' => ($includesubcategories ? '1' : '0'), 'format' => 0); - $form->category = $category->id . ',' . $category->contextid; - $form->defaultmark = 1; - $form->hidden = 1; - $form->stamp = make_unique_id_code(); // Set the unique code (not to be changed). - $question = new stdClass(); - $question->qtype = 'random'; - $question = question_bank::get_qtype('random')->save_question($question, $form); - if (!isset($question->id)) { - print_error('cannotinsertrandomquestion', 'quiz'); - } - quiz_add_quiz_question($question->id, $quiz, $addonpage); - } -} diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 993574ab1e036..6e8ac7b4e1ecb 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -36,9 +36,9 @@ require_once($CFG->dirroot . '/mod/quiz/accessmanager_form.php'); require_once($CFG->dirroot . '/mod/quiz/renderer.php'); require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); -require_once($CFG->dirroot . '/question/editlib.php'); require_once($CFG->libdir . '/eventslib.php'); require_once($CFG->libdir . '/filelib.php'); +require_once($CFG->libdir . '/questionlib.php'); /** @@ -1905,3 +1905,172 @@ function quiz_question_tostring($question, $showicon = false, $showquestiontext return $result; } + +/** + * Verify that the question exists, and the user has permission to use it. + * Does not return. Throws an exception if the question cannot be used. + * @param int $questionid The id of the question. + */ +function quiz_require_question_use($questionid) { + global $DB; + $question = $DB->get_record('question', array('id' => $questionid), '*', MUST_EXIST); + question_require_capability_on($question, 'use'); +} + +/** + * Verify that the question exists, and the user has permission to use it. + * @param object $quiz the quiz settings. + * @param int $slot which question in the quiz to test. + * @return bool whether the user can use this question. + */ +function quiz_has_question_use($quiz, $slot) { + global $DB; + $question = $DB->get_record_sql(" + SELECT q.* + FROM {quiz_slots} slot + JOIN {question} q ON q.id = slot.questionid + WHERE slot.quizid = ? AND slot.slot = ?", array($quiz->id, $slot)); + if (!$question) { + return false; + } + return question_has_capability_on($question, 'use'); +} + +/** + * Add a question to a quiz + * + * Adds a question to a quiz by updating $quiz as well as the + * quiz and quiz_slots tables. It also adds a page break if required. + * @param int $questionid The id of the question to be added + * @param object $quiz The extended quiz object as used by edit.php + * This is updated by this function + * @param int $page Which page in quiz to add the question on. If 0 (default), + * add at the end + * @param float $maxmark The maximum mark to set for this question. (Optional, + * defaults to question.defaultmark. + * @return bool false if the question was already in the quiz + */ +function quiz_add_quiz_question($questionid, $quiz, $page = 0, $maxmark = null) { + global $DB; + $slots = $DB->get_records('quiz_slots', array('quizid' => $quiz->id), + 'slot', 'questionid, slot, page, id'); + if (array_key_exists($questionid, $slots)) { + return false; + } + + $trans = $DB->start_delegated_transaction(); + + $maxpage = 1; + $numonlastpage = 0; + foreach ($slots as $slot) { + if ($slot->page > $maxpage) { + $maxpage = $slot->page; + $numonlastpage = 1; + } else { + $numonlastpage += 1; + } + } + + // Add the new question instance. + $slot = new stdClass(); + $slot->quizid = $quiz->id; + $slot->questionid = $questionid; + + if ($maxmark !== null) { + $slot->maxmark = $maxmark; + } else { + $slot->maxmark = $DB->get_field('question', 'defaultmark', array('id' => $questionid)); + } + + if (is_int($page) && $page >= 1) { + // Adding on a given page. + $lastslotbefore = 0; + foreach (array_reverse($slots) as $otherslot) { + if ($otherslot->page > $page) { + $DB->set_field('quiz_slots', 'slot', $otherslot->slot + 1, array('id' => $otherslot->id)); + } else { + $lastslotbefore = $otherslot->slot; + break; + } + } + $slot->slot = $lastslotbefore + 1; + $slot->page = min($page, $maxpage + 1); + + } else { + $lastslot = end($slots); + if ($lastslot) { + $slot->slot = $lastslot->slot + 1; + } else { + $slot->slot = 1; + } + if ($quiz->questionsperpage && $numonlastpage >= $quiz->questionsperpage) { + $slot->page = $maxpage + 1; + } else { + $slot->page = $maxpage; + } + } + + $DB->insert_record('quiz_slots', $slot); + $trans->allow_commit(); +} + +/** + * Add a random question to the quiz at a given point. + * @param object $quiz the quiz settings. + * @param int $addonpage the page on which to add the question. + * @param int $categoryid the question category to add the question from. + * @param int $number the number of random questions to add. + * @param bool $includesubcategories whether to include questoins from subcategories. + */ +function quiz_add_random_questions($quiz, $addonpage, $categoryid, $number, + $includesubcategories) { + global $DB; + + $category = $DB->get_record('question_categories', array('id' => $categoryid)); + if (!$category) { + print_error('invalidcategoryid', 'error'); + } + + $catcontext = context::instance_by_id($category->contextid); + require_capability('moodle/question:useall', $catcontext); + + // 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_slots} + WHERE questionid = q.id) + ORDER BY id", array($category->id, ($includesubcategories ? '1' : '0')))) { + // Take as many of these as needed. + while (($existingquestion = array_shift($existingquestions)) && $number > 0) { + quiz_add_quiz_question($existingquestion->id, $quiz, $addonpage); + $number -= 1; + } + } + + if ($number <= 0) { + return; + } + + // More random questions are needed, create them. + for ($i = 0; $i < $number; $i += 1) { + $form = new stdClass(); + $form->questiontext = array('text' => ($includesubcategories ? '1' : '0'), 'format' => 0); + $form->category = $category->id . ',' . $category->contextid; + $form->defaultmark = 1; + $form->hidden = 1; + $form->stamp = make_unique_id_code(); // Set the unique code (not to be changed). + $question = new stdClass(); + $question->qtype = 'random'; + $question = question_bank::get_qtype('random')->save_question($question, $form); + if (!isset($question->id)) { + print_error('cannotinsertrandomquestion', 'quiz'); + } + quiz_add_quiz_question($question->id, $quiz, $addonpage); + } +} diff --git a/mod/quiz/questionbank.ajax.php b/mod/quiz/questionbank.ajax.php index 747ca0541dfca..2f5018a650f19 100644 --- a/mod/quiz/questionbank.ajax.php +++ b/mod/quiz/questionbank.ajax.php @@ -25,9 +25,9 @@ define('AJAX_SCRIPT', true); - -require_once('../../config.php'); -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); +require_once(__DIR__ . '/../../config.php'); +require_once($CFG->dirroot . '/mod/quiz/locallib.php'); +require_once($CFG->dirroot . '/question/editlib.php'); list($thispageurl, $contexts, $cmid, $cm, $quiz, $pagevars) = question_edit_setup('editq', '/mod/quiz/edit.php', true); diff --git a/mod/quiz/tests/attempt_walkthrough_from_csv_test.php b/mod/quiz/tests/attempt_walkthrough_from_csv_test.php index 3f96fd90cbaac..25387dbcec837 100644 --- a/mod/quiz/tests/attempt_walkthrough_from_csv_test.php +++ b/mod/quiz/tests/attempt_walkthrough_from_csv_test.php @@ -27,7 +27,6 @@ defined('MOODLE_INTERNAL') || die(); global $CFG; -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); require_once($CFG->dirroot . '/mod/quiz/locallib.php'); /** diff --git a/mod/quiz/tests/attempt_walkthrough_test.php b/mod/quiz/tests/attempt_walkthrough_test.php index 2c0fabbc8dd71..282e453ded77e 100644 --- a/mod/quiz/tests/attempt_walkthrough_test.php +++ b/mod/quiz/tests/attempt_walkthrough_test.php @@ -27,7 +27,6 @@ defined('MOODLE_INTERNAL') || die(); global $CFG; -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); require_once($CFG->dirroot . '/mod/quiz/locallib.php'); /** diff --git a/mod/quiz/tests/events_test.php b/mod/quiz/tests/events_test.php index 4ea32eca833d1..2f92237dac9d6 100644 --- a/mod/quiz/tests/events_test.php +++ b/mod/quiz/tests/events_test.php @@ -27,7 +27,6 @@ global $CFG; require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); /** * Unit tests for quiz events. diff --git a/mod/quiz/tests/lib_test.php b/mod/quiz/tests/lib_test.php index 02703ac05b0fd..cb08add76818f 100644 --- a/mod/quiz/tests/lib_test.php +++ b/mod/quiz/tests/lib_test.php @@ -26,9 +26,6 @@ defined('MOODLE_INTERNAL') || die(); -global $CFG; -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); - /** * @copyright 2008 The Open University diff --git a/mod/quiz/tests/repaginate_test.php b/mod/quiz/tests/repaginate_test.php index 3d664cf2debf2..06cda7d7db569 100644 --- a/mod/quiz/tests/repaginate_test.php +++ b/mod/quiz/tests/repaginate_test.php @@ -25,7 +25,6 @@ defined('MOODLE_INTERNAL') || die(); global $CFG; -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); require_once($CFG->dirroot . '/mod/quiz/locallib.php'); require_once($CFG->dirroot . '/mod/quiz/classes/repaginate.php'); diff --git a/mod/quiz/tests/structure_test.php b/mod/quiz/tests/structure_test.php index 26f60bb03bcab..0a1d84c878535 100644 --- a/mod/quiz/tests/structure_test.php +++ b/mod/quiz/tests/structure_test.php @@ -27,7 +27,6 @@ global $CFG; require_once($CFG->dirroot . '/mod/quiz/attemptlib.php'); -require_once($CFG->dirroot . '/mod/quiz/editlib.php'); /** * Unit tests for quiz events. diff --git a/mod/quiz/upgrade.txt b/mod/quiz/upgrade.txt index 797cd4aaafeba..92c590fa26334 100644 --- a/mod/quiz/upgrade.txt +++ b/mod/quiz/upgrade.txt @@ -23,8 +23,8 @@ This files describes API changes in the quiz code. two scripts get merged in future.) Also questionbank.ajax.php (which may, in future, be made more generic, and moved into the core question bank code.) - As a result of this, mod/quiz/editlib.php is now much shorter than it was. - (In future, expect the remaining code in here to move into mod/quiz/classes.) + As a result of this, mod/quiz/editlib.php has gone. (A few remaining functions + were moved to locallib.php.) Here is a list of all the old functions or classes that have changed. If you used any of these in custom code, you will need to update your code.