diff --git a/admin/tool/qeupgradehelper/locallib.php b/admin/tool/qeupgradehelper/locallib.php index f471b233be6..2c1d933f69c 100644 --- a/admin/tool/qeupgradehelper/locallib.php +++ b/admin/tool/qeupgradehelper/locallib.php @@ -638,10 +638,10 @@ function tool_qeupgradehelper_load_question($questionid, $quizid) { global $CFG, $DB; $question = $DB->get_record_sql(' - SELECT q.*, qqi.grade AS maxmark + SELECT q.*, qqi.maxmark FROM {question} q - JOIN {quiz_question_instances} qqi ON qqi.question = q.id - WHERE q.id = :questionid AND qqi.quiz = :quizid', + JOIN {quiz_question_instances} qqi ON qqi.questionid = q.id + WHERE q.id = :questionid AND qqi.quizid = :quizid', array('questionid' => $questionid, 'quizid' => $quizid)); if (tool_qeupgradehelper_is_upgraded()) { diff --git a/backup/converter/moodle1/lib.php b/backup/converter/moodle1/lib.php index fb9b9e14622..5b0ae4c9beb 100644 --- a/backup/converter/moodle1/lib.php +++ b/backup/converter/moodle1/lib.php @@ -862,6 +862,15 @@ class convert_path { /** * Constructor * + * The optional recipe array can have three keys, and for each key, the value is another array. + * - newfields => array fieldname => defaultvalue indicates fields that have been added to the table, + * and so should be added to the XML. + * - dropfields => array fieldname indicates fieldsthat have been dropped from the table, + * and so can be dropped from the XML. + * - renamefields => array oldname => newname indicates fieldsthat have been renamed in the table, + * and so should be renamed in the XML. + * {@line moodle1_course_outline_handler} is a good example that uses all of these. + * * @param string $name name of the element * @param string $path path of the element * @param array $recipe basic description of the structure conversion diff --git a/mod/quiz/attemptlib.php b/mod/quiz/attemptlib.php index 30c05e69c9a..863064aa527 100644 --- a/mod/quiz/attemptlib.php +++ b/mod/quiz/attemptlib.php @@ -136,8 +136,8 @@ class quiz { throw new moodle_quiz_exception($this, 'noquestions', $this->edit_url()); } $this->questions = question_preload_questions($this->questionids, - 'qqi.grade AS maxmark, qqi.id AS instance', - '{quiz_question_instances} qqi ON qqi.quiz = :quizid AND q.id = qqi.question', + 'qqi.maxmark, qqi.id AS instance', + '{quiz_question_instances} qqi ON qqi.quizid = :quizid AND q.id = qqi.questionid', array('quizid' => $this->quiz->id)); } diff --git a/mod/quiz/backup/moodle1/lib.php b/mod/quiz/backup/moodle1/lib.php index 09efca0df64..02bb98684d5 100644 --- a/mod/quiz/backup/moodle1/lib.php +++ b/mod/quiz/backup/moodle1/lib.php @@ -55,24 +55,31 @@ class moodle1_mod_quiz_handler extends moodle1_mod_handler { 'quiz', '/MOODLE_BACKUP/COURSE/MODULES/MOD/QUIZ', array( 'newfields' => array( - 'showuserpicture' => 0, + 'showuserpicture' => 0, 'questiondecimalpoints' => -1, - 'introformat' => 0, - 'showblocks' => 0, - ) + 'introformat' => 0, + 'showblocks' => 0, + ), ) ), new convert_path('quiz_question_instances', '/MOODLE_BACKUP/COURSE/MODULES/MOD/QUIZ/QUESTION_INSTANCES'), new convert_path('quiz_question_instance', - '/MOODLE_BACKUP/COURSE/MODULES/MOD/QUIZ/QUESTION_INSTANCES/QUESTION_INSTANCE'), + '/MOODLE_BACKUP/COURSE/MODULES/MOD/QUIZ/QUESTION_INSTANCES/QUESTION_INSTANCE', + array( + 'renamefields' => array( + 'question' => 'questionid', + 'grade' => 'maxmark', + ), + ) + ), new convert_path('quiz_feedbacks', '/MOODLE_BACKUP/COURSE/MODULES/MOD/QUIZ/FEEDBACKS'), new convert_path('quiz_feedback', '/MOODLE_BACKUP/COURSE/MODULES/MOD/QUIZ/FEEDBACKS/FEEDBACK', array( 'newfields' => array( - 'feedbacktextformat' => 0 + 'feedbacktextformat' => FORMAT_HTML, ) ) ) diff --git a/mod/quiz/backup/moodle2/backup_quiz_stepslib.php b/mod/quiz/backup/moodle2/backup_quiz_stepslib.php index 63a897a27c0..c258fe0daf1 100644 --- a/mod/quiz/backup/moodle2/backup_quiz_stepslib.php +++ b/mod/quiz/backup/moodle2/backup_quiz_stepslib.php @@ -57,7 +57,7 @@ class backup_quiz_activity_structure_step extends backup_questions_activity_stru $qinstances = new backup_nested_element('question_instances'); $qinstance = new backup_nested_element('question_instance', array('id'), array( - 'question', 'grade')); + 'questionid', 'maxmark')); $feedbacks = new backup_nested_element('feedbacks'); @@ -108,7 +108,7 @@ class backup_quiz_activity_structure_step extends backup_questions_activity_stru $quiz->set_source_table('quiz', array('id' => backup::VAR_ACTIVITYID)); $qinstance->set_source_table('quiz_question_instances', - array('quiz' => backup::VAR_PARENTID)); + array('quizid' => backup::VAR_PARENTID)); $feedback->set_source_table('quiz_feedback', array('quizid' => backup::VAR_PARENTID)); diff --git a/mod/quiz/backup/moodle2/restore_quiz_stepslib.php b/mod/quiz/backup/moodle2/restore_quiz_stepslib.php index b8331a5fab5..5637ac182c9 100644 --- a/mod/quiz/backup/moodle2/restore_quiz_stepslib.php +++ b/mod/quiz/backup/moodle2/restore_quiz_stepslib.php @@ -234,11 +234,17 @@ class restore_quiz_activity_structure_step extends restore_questions_activity_st global $DB; $data = (object)$data; - $oldid = $data->id; - $data->quiz = $this->get_new_parentid('quiz'); + // Backwards compatibility for MDL-43670. + if (!isset($data->questionid) && isset($data->question)) { + $data->questionid = $data->question; + } + if (!isset($data->maxmark) && isset($data->grade)) { + $data->maxmark = $data->grade; + } - $data->question = $this->get_mappingid('question', $data->question); + $data->quizid = $this->get_new_parentid('quiz'); + $data->questionid = $this->get_mappingid('question', $data->questionid); $DB->insert_record('quiz_question_instances', $data); } diff --git a/mod/quiz/db/install.xml b/mod/quiz/db/install.xml index ed0c4ad7ab6..3b0d7de3ae9 100644 --- a/mod/quiz/db/install.xml +++ b/mod/quiz/db/install.xml @@ -101,14 +101,14 @@ - - - + + + - - + +
diff --git a/mod/quiz/db/upgrade.php b/mod/quiz/db/upgrade.php index a1501ee4023..57eb2829701 100644 --- a/mod/quiz/db/upgrade.php +++ b/mod/quiz/db/upgrade.php @@ -17,8 +17,7 @@ /** * Upgrade script for the quiz module. * - * @package mod - * @subpackage quiz + * @package mod_quiz * @copyright 2006 Eloy Lafuente (stronk7) * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ @@ -410,6 +409,97 @@ function xmldb_quiz_upgrade($oldversion) { // Moodle v2.6.0 release upgrade line. // Put any upgrade step following this. + if ($oldversion < 2014011300) { + + // Define key quiz (foreign) to be dropped form quiz_question_instances. + $table = new xmldb_table('quiz_question_instances'); + $key = new xmldb_key('quiz', XMLDB_KEY_FOREIGN, array('quiz'), 'quiz', array('id')); + + // Launch drop key quiz. + $dbman->drop_key($table, $key); + + // Quiz savepoint reached. + upgrade_mod_savepoint(true, 2014011300, 'quiz'); + } + + if ($oldversion < 2014011301) { + + // Rename field quiz on table quiz_question_instances to quizid. + $table = new xmldb_table('quiz_question_instances'); + $field = new xmldb_field('quiz', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id'); + + // Launch rename field quiz. + $dbman->rename_field($table, $field, 'quizid'); + + // Quiz savepoint reached. + upgrade_mod_savepoint(true, 2014011301, 'quiz'); + } + + if ($oldversion < 2014011302) { + + // Define key quizid (foreign) to be added to quiz_question_instances. + $table = new xmldb_table('quiz_question_instances'); + $key = new xmldb_key('quizid', XMLDB_KEY_FOREIGN, array('quizid'), 'quiz', array('id')); + + // Launch add key quizid. + $dbman->add_key($table, $key); + + // Quiz savepoint reached. + upgrade_mod_savepoint(true, 2014011302, 'quiz'); + } + + if ($oldversion < 2014011303) { + + // Define key question (foreign) to be dropped form quiz_question_instances. + $table = new xmldb_table('quiz_question_instances'); + $key = new xmldb_key('question', XMLDB_KEY_FOREIGN, array('question'), 'question', array('id')); + + // Launch drop key question. + $dbman->drop_key($table, $key); + + // Quiz savepoint reached. + upgrade_mod_savepoint(true, 2014011303, 'quiz'); + } + + if ($oldversion < 2014011304) { + + // Rename field question on table quiz_question_instances to questionid. + $table = new xmldb_table('quiz_question_instances'); + $field = new xmldb_field('question', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'quiz'); + + // Launch rename field question. + $dbman->rename_field($table, $field, 'questionid'); + + // Quiz savepoint reached. + upgrade_mod_savepoint(true, 2014011304, 'quiz'); + } + + if ($oldversion < 2014011305) { + + // Define key questionid (foreign) to be added to quiz_question_instances. + $table = new xmldb_table('quiz_question_instances'); + $key = new xmldb_key('questionid', XMLDB_KEY_FOREIGN, array('questionid'), 'question', array('id')); + + // Launch add key questionid. + $dbman->add_key($table, $key); + + // Quiz savepoint reached. + upgrade_mod_savepoint(true, 2014011305, 'quiz'); + } + + if ($oldversion < 2014011306) { + + // Rename field grade on table quiz_question_instances to maxmark. + $table = new xmldb_table('quiz_question_instances'); + $field = new xmldb_field('grade', XMLDB_TYPE_NUMBER, '12, 7', null, XMLDB_NOTNULL, null, '0', 'question'); + + // Launch rename field grade. + $dbman->rename_field($table, $field, 'maxmark'); + + // Quiz savepoint reached. + upgrade_mod_savepoint(true, 2014011306, 'quiz'); + } + return true; } diff --git a/mod/quiz/editlib.php b/mod/quiz/editlib.php index 13a42778018..aa8ef8feb74 100644 --- a/mod/quiz/editlib.php +++ b/mod/quiz/editlib.php @@ -75,7 +75,7 @@ function quiz_remove_question($quiz, $questionid) { $quiz->questions = implode(',', $questionids); $DB->set_field('quiz', 'questions', $quiz->questions, array('id' => $quiz->id)); $DB->delete_records('quiz_question_instances', - array('quiz' => $quiz->instance, 'question' => $questionid)); + array('quizid' => $quiz->instance, 'questionid' => $questionid)); } /** @@ -168,9 +168,9 @@ function quiz_add_quiz_question($id, $quiz, $page = 0) { // Add the new question instance. $instance = new stdClass(); - $instance->quiz = $quiz->id; - $instance->question = $id; - $instance->grade = $DB->get_field('question', 'defaultmark', array('id' => $id)); + $instance->quizid = $quiz->id; + $instance->questionid = $id; + $instance->maxmark = $DB->get_field('question', 'defaultmark', array('id' => $id)); $DB->insert_record('quiz_question_instances', $instance); } @@ -196,7 +196,7 @@ function quiz_add_random_questions($quiz, $addonpage, $categoryid, $number, AND NOT EXISTS ( SELECT * FROM {quiz_question_instances} - WHERE question = q.id) + WHERE questionid = q.id) ORDER BY id", array($category->id, $includesubcategories))) { // Take as many of these as needed. while (($existingquestion = array_shift($existingquestions)) && $number > 0) { @@ -280,29 +280,29 @@ function quiz_save_new_layout($quiz) { * Saves changes to the question grades in the quiz_question_instances table. * It does not update 'sumgrades' in the quiz table. * - * @param int grade The maximal grade for the question - * @param int $questionid The id of the question - * @param int $quizid The id of the quiz to update / add the instances for. + * @param float $maxmark the maximal grade for the question. + * @param int $questionid the question id. + * @param stdClass $quiz the quiz settings. */ -function quiz_update_question_instance($grade, $questionid, $quiz) { +function quiz_update_question_instance($maxmark, $questionid, $quiz) { global $DB; - $instance = $DB->get_record('quiz_question_instances', array('quiz' => $quiz->id, - 'question' => $questionid)); + $instance = $DB->get_record('quiz_question_instances', array('quizid' => $quiz->id, + 'questionid' => $questionid)); $slot = quiz_get_slot_for_question($quiz, $questionid); if (!$instance || !$slot) { - throw new coding_exception('Attempt to change the grade of a quesion not in the quiz.'); + throw new coding_exception('Attempt to change the max mark of a quesion not in the quiz.'); } - if (abs($grade - $instance->grade) < 1e-7) { + if (abs($maxmark - $instance->maxmark) < 1e-7) { // Grade has not changed. Nothing to do. return; } - $instance->grade = $grade; + $instance->maxmark = $maxmark; $DB->update_record('quiz_question_instances', $instance); question_engine::set_max_mark_in_attempts(new qubaids_for_quiz($quiz->id), - $slot, $grade); + $slot, $maxmark); } // Private function used by the following two. @@ -392,11 +392,11 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete, $reordertool, if ($quiz->questions) { list($usql, $params) = $DB->get_in_or_equal(explode(',', $quiz->questions)); $params[] = $quiz->id; - $questions = $DB->get_records_sql("SELECT q.*, qc.contextid, qqi.grade as maxmark + $questions = $DB->get_records_sql("SELECT q.*, qc.contextid, qqi.maxmark FROM {question} q JOIN {question_categories} qc ON qc.id = q.category - JOIN {quiz_question_instances} qqi ON qqi.question = q.id - WHERE q.id $usql AND qqi.quiz = ?", $params); + JOIN {quiz_question_instances} qqi ON qqi.questionid = q.id + WHERE q.id $usql AND qqi.quizid = ?", $params); } else { $questions = array(); } diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index 0fc90d93eda..6dac7386ebd 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -170,7 +170,7 @@ function quiz_delete_instance($id) { quiz_delete_all_attempts($quiz); quiz_delete_all_overrides($quiz); - $DB->delete_records('quiz_question_instances', array('quiz' => $quiz->id)); + $DB->delete_records('quiz_question_instances', array('quizid' => $quiz->id)); $DB->delete_records('quiz_feedback', array('quizid' => $quiz->id)); $events = $DB->get_records('event', array('modulename' => 'quiz', 'instance' => $quiz->id)); @@ -1283,7 +1283,7 @@ function quiz_questions_in_use($questionids) { require_once($CFG->libdir . '/questionlib.php'); list($test, $params) = $DB->get_in_or_equal($questionids); return $DB->record_exists_select('quiz_question_instances', - 'question ' . $test, $params) || question_engine::questions_in_use( + 'questionid ' . $test, $params) || question_engine::questions_in_use( $questionids, new qubaid_join('{quiz_attempts} quiza', 'quiza.uniqueid', 'quiza.preview = 0')); } diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index 04ac5736e83..8b93a9e2164 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -486,20 +486,20 @@ function quiz_get_all_question_grades($quiz) { $wheresql = ''; if (!is_null($questionlist)) { list($usql, $question_params) = $DB->get_in_or_equal(explode(',', $questionlist)); - $wheresql = " AND question $usql "; + $wheresql = ' AND questionid ' . $usql; $params = array_merge($params, $question_params); } - $instances = $DB->get_records_sql("SELECT question, grade, id + $instances = $DB->get_records_sql("SELECT questionid, maxmark, id FROM {quiz_question_instances} - WHERE quiz = ? $wheresql", $params); + WHERE quizid = ?{$wheresql}", $params); - $list = explode(",", $questionlist); + $list = explode(',', $questionlist); $grades = array(); foreach ($list as $qid) { if (isset($instances[$qid])) { - $grades[$qid] = $instances[$qid]->grade; + $grades[$qid] = $instances[$qid]->maxmark; } else { $grades[$qid] = 1; } @@ -601,9 +601,9 @@ function quiz_update_sumgrades($quiz) { $sql = 'UPDATE {quiz} SET sumgrades = COALESCE(( - SELECT SUM(grade) + SELECT SUM(maxmark) FROM {quiz_question_instances} - WHERE quiz = {quiz}.id + WHERE quizid = {quiz}.id ), 0) WHERE id = ?'; $DB->execute($sql, array($quiz->id)); diff --git a/mod/quiz/report/reportlib.php b/mod/quiz/report/reportlib.php index 8e317fda935..cd01c64aaed 100644 --- a/mod/quiz/report/reportlib.php +++ b/mod/quiz/report/reportlib.php @@ -97,15 +97,15 @@ function quiz_report_get_significant_questions($quiz) { SELECT q.id, q.length, - qqi.grade AS maxmark + qqi.maxmark FROM {question} q -JOIN {quiz_question_instances} qqi ON qqi.question = q.id +JOIN {quiz_question_instances} qqi ON qqi.questionid = q.id WHERE q.id $usql AND - qqi.quiz = ? AND - length > 0", $params); + qqi.quizid = ? AND + q.length > 0", $params); $qsbyslot = array(); $number = 1; diff --git a/mod/quiz/upgrade.txt b/mod/quiz/upgrade.txt index a7b53267c3f..6b638870e51 100644 --- a/mod/quiz/upgrade.txt +++ b/mod/quiz/upgrade.txt @@ -1,5 +1,13 @@ This files describes API changes in the quiz code. +=== 2.7 === + +* The columns of the quiz_question_instances table have been renamed to match + the coding guidelines. Specifically + quiz -> quizid + question -> questionid + grade -> maxmark + === 2.6 === * As part of improving the page usability and accessibility, we updated the diff --git a/mod/quiz/version.php b/mod/quiz/version.php index c7e6d14ff12..c0b8fdce86c 100644 --- a/mod/quiz/version.php +++ b/mod/quiz/version.php @@ -25,7 +25,7 @@ defined('MOODLE_INTERNAL') || die(); -$module->version = 2013110501; // The current module version (Date: YYYYMMDDXX). +$module->version = 2014011306; // The current module version (Date: YYYYMMDDXX). $module->requires = 2013110500; // Requires this Moodle version. $module->component = 'mod_quiz'; // Full name of the plugin (used for diagnostics). $module->cron = 60; diff --git a/question/type/calculated/questiontype.php b/question/type/calculated/questiontype.php index 75a047e9a30..443af178dcd 100644 --- a/question/type/calculated/questiontype.php +++ b/question/type/calculated/questiontype.php @@ -1705,28 +1705,19 @@ class qtype_calculated extends question_type { } $line++; $text .= ""; - $nbofquiz = 0; - $nbofattempts= 0; - $usedinquiz = false; - if ($list = $DB->get_records('quiz_question_instances', - array('question' => $qu->id))) { - $usedinquiz = true; - foreach ($list as $key => $li) { - $nbofquiz ++; - if ($att = $DB->get_records('quiz_attempts', - array('quiz' => $li->quiz, 'preview' => '0'))) { - $nbofattempts+= count($att); - } - } - } - if ($usedinquiz) { + // TODO should not have quiz-specific code here. + $nbofquiz = $DB->count_records('quiz_question_instances', array('questionid' => $qu->id)); + $nbofattempts = $DB->count_records_sql(" + SELECT count(1) + FROM {quiz_question_instances} qqi + JOIN {quiz_attempts} quiza ON quiza.quiz = qqi.quizid + WHERE qqi.questionid = ? + AND quiza.preview = 0", array($qu->id)); + if ($nbofquiz > 0) { $text .= ""; - } else { - $text .= ""; - } - if ($usedinquiz) { $text .= ""; $text .= "
$qu->name$nbofquiz0$nbofattempts"; } else { + $text .= "0
"; } diff --git a/question/type/multianswer/edit_multianswer_form.php b/question/type/multianswer/edit_multianswer_form.php index 8bcdb2b512a..6a803384b2a 100644 --- a/question/type/multianswer/edit_multianswer_form.php +++ b/question/type/multianswer/edit_multianswer_form.php @@ -63,18 +63,16 @@ class qtype_multianswer_edit_form extends question_edit_form { $this->used_in_quiz = false; if (isset($question->id) && $question->id != 0) { + // TODO should not have quiz-specific code here. $this->savedquestiondisplay = fullclone($question); - if ($list = $DB->get_records('quiz_question_instances', - array('question' => $question->id))) { - foreach ($list as $key => $li) { - $this->nb_of_quiz ++; - if ($att = $DB->get_records('quiz_attempts', - array('quiz' => $li->quiz, 'preview' => '0'))) { - $this->nb_of_attempts += count($att); - $this->used_in_quiz = true; - } - } - } + $this->nb_of_quiz = $DB->count_records('quiz_question_instances', array('questionid' => $question->id)); + $this->used_in_quiz = $this->nb_of_quiz > 0; + $this->nb_of_attempts = $DB->count_records_sql(" + SELECT count(1) + FROM {quiz_question_instances} qqi + JOIN {quiz_attempts} quiza ON quiza.quiz = qqi.quizid + WHERE qqi.questionid = ? + AND quiza.preview = 0", array($question->id)); } parent::__construct($submiturl, $question, $category, $contexts, $formeditable);