merging MOODLE_19_QUESTIONS with HEAD

This commit is contained in:
jamiesensei 2007-08-09 21:51:09 +00:00
parent 3bee1ead40
commit 271e6decda
47 changed files with 2807 additions and 1546 deletions

View file

@ -29,27 +29,54 @@
// When we backup a quiz we also need to backup the questions and possibly
// the data about student interaction with the questions. The functions to do
// that are included with the following library
require_once("$CFG->libdir/questionlib.php");
require_once("$CFG->dirroot/question/backuplib.php");
//STEP 1. Backup categories/questions and associated structures
// (course independent)
//Insert necessary category ids to backup_ids table
function insert_category_ids($course, $backup_unique_code, $instances = null) {
/*
* Insert necessary category ids to backup_ids table. Called during backup_check.html
*/
function insert_category_and_question_ids($course, $backup_unique_code, $instances = null) {
global $CFG;
include_once("$CFG->dirroot/mod/quiz/lib.php");
// Create missing categories and reasign orphaned questions.
fix_orphaned_questions($course);
// First, ALL categories from this course.
// First, all categories from this course's context.
$coursecontext = get_context_instance(CONTEXT_COURSE, $course);
$status = execute_sql("INSERT INTO {$CFG->prefix}backup_ids
(backup_code, table_name, old_id, info)
SELECT '$backup_unique_code', 'question_categories', qc.id, ''
FROM {$CFG->prefix}question_categories qc
WHERE qc.course = $course", false);
WHERE qc.contextid = {$coursecontext->id}", false);
// Then published categories from other courses used by the quizzes we are backing up.
// then, all categories from this course's modules' contexts.
// using 'dummykeyname' in sql because otherwise get_records_sql_menu returns an error
// if two key names are the same.
$cmcontexts = get_records_sql_menu("SELECT c.id, c.id AS dummykeyname FROM `{$CFG->prefix}modules` AS `mod`,
`{$CFG->prefix}course_modules` AS `cm`,
`{$CFG->prefix}context` as `c`
WHERE mod.name = 'quiz' AND mod.id = cm.module AND cm.id = c.instanceid
AND c.contextlevel = ".CONTEXT_MODULE." AND cm.course = $course");
if ($cmcontexts){
$status = $status && execute_sql("INSERT INTO {$CFG->prefix}backup_ids
(backup_code, table_name, old_id, info)
SELECT '$backup_unique_code', 'question_categories', qc.id, ''
FROM {$CFG->prefix}question_categories qc
WHERE qc.contextid IN (".join(array_keys($cmcontexts), ', ').")", false);
}
//put the ids of the questions from all these categories into the db.
$status = $status && execute_sql("INSERT INTO {$CFG->prefix}backup_ids
(backup_code, table_name, old_id, info)
SELECT '$backup_unique_code', 'question', q.id, ''
FROM {$CFG->prefix}question AS q, {$CFG->prefix}backup_ids AS bk
WHERE q.category = bk.old_id AND bk.table_name = 'question_categories' AND
bk.backup_code = '$backup_unique_code'", false);
// Then categories from parent contexts used by the quizzes we are backing up.
//TODO this will need generalising when we have modules other than quiz using shared questions above course level.
$parentcontexts = get_parent_contexts($coursecontext);
$from = "{$CFG->prefix}quiz quiz,";
$where = "AND quiz.course = '$course'
AND qqi.quiz = quiz.id";
if (!empty($instances) && is_array($instances) && count($instances)) {
$questionselectsqlfrom = '';
$questionselectsqlwhere = 'AND qqi.quiz IN ('.implode(',',array_keys($instances)).')';
@ -61,7 +88,7 @@
$categoriesinothercourses = get_records_sql("
SELECT id, parent, 0 AS childrendone
FROM {$CFG->prefix}question_categories
WHERE course <> $course
WHERE contextid IN (".join($parentcontexts, ', ').")
AND id IN (
SELECT DISTINCT question.category
FROM {$CFG->prefix}question question,
@ -70,63 +97,90 @@
WHERE qqi.question = question.id
$questionselectsqlwhere
)", false);
if (!$categoriesinothercourses) {
$categoriesinothercourses = array();
}
if (!$categories) {
$categories = array();
} else {
//put the ids of the used questions from all these categories into the db.
$status = $status && execute_sql("INSERT INTO {$CFG->prefix}backup_ids
(backup_code, table_name, old_id, info)
SELECT '$backup_unique_code', 'question', q.id, ''
FROM {$CFG->prefix}question q,
$from
{$CFG->prefix}question_categories qc,
{$CFG->prefix}quiz_question_instances qqi
WHERE (qqi.question = q.id
OR qqi.question = q.parent)
AND q.category = qc.id
AND qc.contextid IN (".join($parentcontexts, ', ').")
$where", false);
// Add the parent categories, of these categories up to the top of the category tree.
foreach ($categoriesinothercourses as $category) {
while ($category->parent != 0) {
if (array_key_exists($category->parent, $categoriesinothercourses)) {
// Parent category already on the list.
break;
}
$currentid = $category->id;
$category = get_record('question_categories', 'id', $category->parent, '', '', '', '', 'id, parent, 0 AS childrendone');
if ($category) {
$categoriesinothercourses[$category->id] = $category;
} else {
// Parent not found: this indicates an error, but just fix it.
set_field('question_categories', 'parent', 0, 'id', $currentid);
break;
// Add the parent categories, of these categories up to the top of the category tree.
// not backing up the questions in these categories.
foreach ($categories as $category) {
while ($category->parent != 0) {
if (array_key_exists($category->parent, $categories)) {
// Parent category already on the list.
break;
}
$currentid = $category->id;
$category = get_record('question_categories', 'id', $category->parent, '', '', '', '', 'id, parent, 0 AS childrendone');
if ($category) {
$categories[$category->id] = $category;
} else {
// Parent not found: this indicates an error, but just fix it.
set_field('question_categories', 'parent', 0, 'id', $currentid);
break;
}
}
}
}
// Now we look for random questions used in our quizzes
// that select from subcategories in other courses. That implies
// those subcategories also need to be backed up. (The categories themselves
// and their parents will already have been included.)
$categorieswithrandom = get_records_sql("
SELECT DISTINCT question.category AS id
FROM {$CFG->prefix}quiz_question_instances qqi,
$questionselectsqlfrom
{$CFG->prefix}question question
WHERE question.id = qqi.question
AND question.qtype = '" . RANDOM . "'
AND question.questiontext = '1'
$questionselectsqlwhere
");
if ($categorieswithrandom) {
foreach ($categorieswithrandom as $category) {
if (isset($categoriesinothercourses[$category->id])){
$status = quiz_backup_add_sub_categories($categoriesinothercourses, $category->id);
// Now we look for categories from other courses containing random questions
// in our quizzes that select from the category and its subcategories. That implies
// those subcategories also need to be backed up. (The categories themselves
// and their parents will already have been included.)
$categorieswithrandom = get_records_sql("
SELECT question.category AS id, SUM(question.questiontext) as questiontext
FROM {$CFG->prefix}quiz_question_instances qqi,
$from
{$CFG->prefix}question question
WHERE question.id = qqi.question
AND question.qtype = '" . RANDOM . "'
$where
GROUP BY question.category
");
$randomselectedquestions = array();
if ($categorieswithrandom) {
foreach ($categorieswithrandom as $category) {
if ($category->questiontext){
$status = $status && quiz_backup_add_sub_categories($categories, $randomselectedquestions, $category->id);
}
}
$returnval = get_records_sql("
SELECT question.id
FROM {$CFG->prefix}question question
WHERE question.category IN (".join(array_keys($categorieswithrandom), ', ').")");
if ($returnval) {
$randomselectedquestions += $returnval;
}
}
}
// Finally, add all these extra categories to the backup_ids table.
foreach ($categoriesinothercourses as $category) {
$status = $status && backup_putid($backup_unique_code, 'question_categories', $category->id, 0);
// Finally, add all these extra categories to the backup_ids table.
foreach ($categories as $category) {
$status = $status && backup_putid($backup_unique_code, 'question_categories', $category->id, 0);
}
// Finally, add all these extra categories to the backup_ids table.
foreach ($randomselectedquestions as $question) {
$status = $status && backup_putid($backup_unique_code, 'question', $question->id, 0);
}
}
return $status;
}
/**
* Helper function adding the id of all the subcategories of a category to an array.
*/
function quiz_backup_add_sub_categories(&$categories, $categoryid) {
function quiz_backup_add_sub_categories(&$categories, &$questions, $categoryid) {
global $CFG;
$status = true;
if ($categories[$categoryid]->childrendone) {
return $status;
@ -136,7 +190,16 @@
if (!array_key_exists($subcategory->id, $categories)) {
$categories[$subcategory->id] = $subcategory;
}
$status = $status && quiz_backup_add_sub_categories($categories, $subcategory->id);
$status = $status && quiz_backup_add_sub_categories($categories, $questions, $subcategory->id);
}
$subcatlist = join(array_keys($subcategories), ',');
$returnval = get_records_sql("
SELECT question.id
FROM {$CFG->prefix}question question
WHERE question.category IN ($subcatlist)
");
if ($returnval) {
$questions += $returnval;
}
}
$categories[$categoryid]->childrendone = 1;
@ -166,10 +229,10 @@
if (!$exist) {
//Build a new category
$db_cat = new stdClass;
$db_cat->course = $course;
// always create missing categories in course context
$db_cat->contextid = get_context_instance(CONTEXT_COURSE, $course);
$db_cat->name = get_string('recreatedcategory','',$key);
$db_cat->info = get_string('recreatedcategory','',$key);
$db_cat->publish = 1;
$db_cat->stamp = make_unique_id_code();
//Insert the new category
$catid = insert_record('question_categories',$db_cat);
@ -453,11 +516,14 @@
////Return an array of info (name,value)
/// $instances is an array with key = instanceid, value = object (name,id,userdata)
function quiz_check_backup_mods($course,$user_data= false,$backup_unique_code,$instances=null) {
//Deletes data from mdl_backup_ids (categories section)
delete_category_ids ($backup_unique_code);
//Create date into mdl_backup_ids (categories section)
insert_category_ids ($course,$backup_unique_code,$instances);
delete_ids ($backup_unique_code, 'question_categories');
delete_ids ($backup_unique_code, 'question');
//this function selects all the questions / categories to be backed up.
insert_category_and_question_ids($course, $backup_unique_code, $instances);
if ($course != SITEID){
question_insert_site_file_names($course, $backup_unique_code);
}
if (!empty($instances) && is_array($instances) && count($instances)) {
$info = array();
foreach ($instances as $id => $instance) {

View file

@ -1,17 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/quiz/db" VERSION="20070228" COMMENT="XMLDB file for Moodle mod/quiz"
<XMLDB PATH="mod/quiz/db" VERSION="20070522" COMMENT="XMLDB file for Moodle mod/quiz"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="question_categories" COMMENT="Categories are for grouping questions" NEXT="question">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="course"/>
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="course" NEXT="info"/>
<FIELD NAME="info" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="publish"/>
<FIELD NAME="publish" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="info" NEXT="stamp"/>
<FIELD NAME="stamp" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="publish" NEXT="parent"/>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="contextid"/>
<FIELD NAME="contextid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="context that this category is shared in" PREVIOUS="name" NEXT="info"/>
<FIELD NAME="info" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="contextid" NEXT="stamp"/>
<FIELD NAME="stamp" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="info" NEXT="parent"/>
<FIELD NAME="parent" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="stamp" NEXT="sortorder"/>
<FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="999" SEQUENCE="false" ENUM="false" PREVIOUS="parent"/>
</FIELDS>
@ -20,7 +19,7 @@
<KEY NAME="parent" TYPE="foreign" FIELDS="parent" REFTABLE="question_categories" REFFIELDS="id" COMMENT="note that to make this recursive FK working someday, the parent field must be declared NULL" PREVIOUS="primary"/>
</KEYS>
<INDEXES>
<INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
<INDEX NAME="contextid" UNIQUE="false" FIELDS="contextid" COMMENT="links to context table"/>
</INDEXES>
</TABLE>
<TABLE NAME="question" COMMENT="The questions themselves" PREVIOUS="question_categories" NEXT="question_answers">
@ -39,12 +38,18 @@
<FIELD NAME="length" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="1" SEQUENCE="false" ENUM="false" PREVIOUS="qtype" NEXT="stamp"/>
<FIELD NAME="stamp" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="length" NEXT="version"/>
<FIELD NAME="version" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="stamp" NEXT="hidden"/>
<FIELD NAME="hidden" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="version"/>
<FIELD NAME="hidden" TYPE="int" LENGTH="1" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="version" NEXT="timecreated"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="time question was created" PREVIOUS="hidden" NEXT="timemodified"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="time that question was last modified" PREVIOUS="timecreated" NEXT="createdby"/>
<FIELD NAME="createdby" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="userid of person who created this question" PREVIOUS="timemodified" NEXT="modifiedby"/>
<FIELD NAME="modifiedby" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="userid of person who last edited this question" PREVIOUS="createdby"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="Primary key for question" NEXT="category"/>
<KEY NAME="category" TYPE="foreign" FIELDS="category" REFTABLE="question_categories" REFFIELDS="id" PREVIOUS="primary" NEXT="parent"/>
<KEY NAME="parent" TYPE="foreign" FIELDS="parent" REFTABLE="question" REFFIELDS="id" COMMENT="note that to make this recursive FK working someday, the parent field must be declared NULL" PREVIOUS="category"/>
<KEY NAME="parent" TYPE="foreign" FIELDS="parent" REFTABLE="question" REFFIELDS="id" COMMENT="note that to make this recursive FK working someday, the parent field must be declared NULL" PREVIOUS="category" NEXT="createdby"/>
<KEY NAME="createdby" TYPE="foreign" FIELDS="createdby" REFTABLE="user" REFFIELDS="id" COMMENT="foreign (createdby) references user (id)" PREVIOUS="parent" NEXT="modifiedby"/>
<KEY NAME="modifiedby" TYPE="foreign" FIELDS="modifiedby" REFTABLE="user" REFFIELDS="id" COMMENT="foreign (modifiedby) references user (id)" PREVIOUS="createdby"/>
</KEYS>
</TABLE>
<TABLE NAME="question_answers" COMMENT="Answers, with a fractional grade (0-1) and feedback" PREVIOUS="question" NEXT="question_dataset_definitions">

View file

@ -1,6 +1,6 @@
<?php //$Id$
// This file keeps track of upgrades to
// This file keeps track of upgrades to
// the quiz module
//
// Sometimes, changes between versions involve
@ -19,12 +19,12 @@
function xmldb_quiz_upgrade($oldversion=0) {
global $CFG, $THEME, $db;
global $CFG, $THEME;
$result = true;
/// And upgrade begins here. For each one, you'll need one
/// block of code similar to the next one. Please, delete
/// And upgrade begins here. For each one, you'll need one
/// block of code similar to the next one. Please, delete
/// this comment lines once this file start handling proper
/// upgrade code.
@ -68,7 +68,7 @@ function xmldb_quiz_upgrade($oldversion=0) {
// Separate control for when overall feedback is displayed, independant of the question feedback settings.
if ($result && $oldversion < 2007072600) {
// Adjust the quiz review options so that overall feedback is displayed whenever feedback is.
$result = $result && execute_sql('UPDATE ' . $CFG->prefix . 'quiz SET review = ' .
sql_bitor(sql_bitand('review', sql_bitnot(QUIZ_REVIEW_OVERALLFEEDBACK)),
@ -82,7 +82,7 @@ function xmldb_quiz_upgrade($oldversion=0) {
(($CFG->quiz_review & QUIZ_REVIEW_FEEDBACK & QUIZ_REVIEW_OPEN) << 14) |
(($CFG->quiz_review & QUIZ_REVIEW_FEEDBACK & QUIZ_REVIEW_CLOSED) << 12));
}
return $result;
}

View file

@ -30,12 +30,12 @@
require_once($CFG->dirroot.'/mod/quiz/editlib.php');
/**
* Callback function called from question_list() function (which is called from showbank()
* Callback function called from question_list() function (which is called from showbank())
* Displays action icon as first action for each question.
*/
function module_specific_actions($pageurl, $questionid, $cmid){
function module_specific_actions($pageurl, $questionid, $cmid, $canuse){
global $CFG;
if (has_capability("mod/quiz:manage", get_context_instance(CONTEXT_MODULE, $cmid))){
if ($canuse){
$straddtoquiz = get_string("addtoquiz", "quiz");
$out = "<a title=\"$straddtoquiz\" href=\"edit.php?".$pageurl->get_query_string()."&amp;addquestion=$questionid&amp;sesskey=".sesskey()."\"><img
src=\"$CFG->pixpath/t/moveleft.gif\" alt=\"$straddtoquiz\" /></a>&nbsp;";
@ -45,28 +45,24 @@
}
}
/**
* Callback function called from question_list() function (which is called from showbank()
* 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){
global $THEME;
if (has_capability("mod/quiz:manage", get_context_instance(CONTEXT_MODULE, $cmid))){
$straddtoquiz = get_string("addtoquiz", "quiz");
$out = "<input type=\"submit\" name=\"add\" value=\"{$THEME->larrow} $straddtoquiz\" />\n";
$out .= '</td><td>';
return $out;
} else {
return '';
}
$straddtoquiz = get_string("addtoquiz", "quiz");
$out = "<input type=\"submit\" name=\"add\" value=\"{$THEME->larrow} $straddtoquiz\" />\n";
echo '<br />';
return $out;
}
/**
* Callback function called from question_list() function (which is called from showbank()
* Displays button in form with checkboxes for each question.
* Callback function called from question_list() function (which is called from showbank())
*/
function module_specific_controls($totalnumber, $recurse, $categoryid, $cmid){
if (has_capability("mod/quiz:manage", get_context_instance(CONTEXT_MODULE, $cmid))){
function module_specific_controls($totalnumber, $recurse, $category, $cmid){
$catcontext = get_context_instance_by_id($category->contextid);
if (has_capability('moodle/question:useall', $catcontext)){
for ($i = 1;$i <= min(10, $totalnumber); $i++) {
$randomcount[$i] = $i;
}
@ -76,16 +72,16 @@
$out = '<br />';
$out .= get_string('addrandom', 'quiz', choose_from_menu($randomcount, 'randomcount', '1', '', '', '', true));
$out .= '<input type="hidden" name="recurse" value="'.$recurse.'" />';
$out .= "<input type=\"hidden\" name=\"categoryid\" value=\"$categoryid\" />";
$out .= "<input type=\"hidden\" name=\"categoryid\" value=\"$category->id\" />";
$out .= ' <input type="submit" name="addrandom" value="'. get_string('add') .'" />';
$out .= helpbutton('random', get_string('random', 'quiz'), 'quiz', true, false, '', true);
return $out;
} else {
return '';
$out = '';
}
}
list($thispageurl, $courseid, $cmid, $cm, $quiz, $pagevars) = question_edit_setup(true);
return $out;
}
list($thispageurl, $contexts, $cmid, $cm, $quiz, $pagevars) = question_edit_setup('editq', true);
//these params are only passed from page request to request while we stay on this page
//otherwise they would go in question_edit_setup
@ -99,12 +95,12 @@
if ($quiz_reordertool != 0) {
$thispageurl->param('reordertool', $quiz_reordertool);
}
$strquizzes = get_string('modulenameplural', 'quiz');
$strquiz = get_string('modulename', 'quiz');
$streditingquestions = get_string('editquestions', "quiz");
$streditingquiz = get_string('editinga', 'moodle', $strquiz);
@ -112,15 +108,14 @@
if (! $course = get_record("course", "id", $quiz->course)) {
error("This course doesn't exist");
}
$coursecontext = get_context_instance(CONTEXT_COURSE, $quiz->course);
$quizcontext = get_context_instance(CONTEXT_MODULE, $quiz->cmid);
// Log this visit.
add_to_log($cm->course, 'quiz', 'editquestions',
"view.php?id=$cm->id", "$quiz->id", $cm->id);
require_capability('mod/quiz:manage', $quizcontext);
//you need mod/quiz:manage in addition to question capabilities to access this page.
require_capability('mod/quiz:manage', $contexts->lowest());
if (isset($quiz->instance)
&& empty($quiz->grades)){ // Construct an array to hold all the grades.
@ -187,6 +182,8 @@
if (! $category = get_record('question_categories', 'id', $categoryid)) {
error('Category ID is incorrect');
}
$catcontext = get_context_instance_by_id($category->contextid);
require_capability('moodle/question:useall', $catcontext);
$category->name = addslashes($category->name);
// find existing random questions in this category
$random = RANDOM;
@ -214,7 +211,7 @@
if ($randomcreate > 0) {
$form->name = get_string('random', 'quiz') .' ('. $category->name .')';
$form->category = $category->id;
$form->category = "$category->id,$category->contextid";
$form->questiontext = $recurse; // we use the questiontext field to store the info
// on whether to include questions in subcategories
$form->questiontextformat = 0;
@ -246,7 +243,6 @@
error('Could not save layout');
}
}
if (isset($_REQUEST['delete']) and confirm_sesskey()) { /// Remove a question from the quiz
quiz_delete_quiz_question($_REQUEST['delete'], $quiz);
}
@ -267,7 +263,7 @@
$questions[$value] = $oldquestions[$key];
}
}
// If ordering info was given, reorder the questions
if ($questions) {
ksort($questions);
@ -296,26 +292,23 @@
delete_records('quiz_attempts', 'preview', '1', 'quiz', $quiz->id);
}
/// all commands have been dealt with, now print the page
question_showbank_actions($thispageurl, $cm);
if (empty($quiz->category) or !record_exists('question_categories', 'id', $quiz->category)) {
$category = get_default_question_category($course->id);
$quiz->category = $category->id;
}
/// all commands have been dealt with, now print the page
// Print basic page layout.
if (isset($quiz->instance) and record_exists_select('quiz_attempts', "quiz = '$quiz->instance' AND preview = '0'")){
// one column layout with table of questions used in this quiz
$strupdatemodule = has_capability('moodle/course:manageactivities', $coursecontext)
$strupdatemodule = has_capability('moodle/course:manageactivities', $contexts->lowest())
? update_module_button($cm->id, $course->id, get_string('modulename', 'quiz'))
: "";
$navlinks = array();
$navlinks[] = array('name' => $strquizzes, 'link' => "index.php?id=$course->id", 'type' => 'activity');
$navlinks[] = array('name' => format_string($quiz->name), 'link' => "view.php?q=$quiz->instance", 'type' => 'activityinstance');
$navlinks[] = array('name' => $strquizzes, 'link' => "index.php?id=$course->id", 'type' => 'activity');
$navlinks[] = array('name' => format_string($quiz->name), 'link' => "view.php?q=$quiz->instance", 'type' => 'activityinstance');
$navlinks[] = array('name' => $streditingquiz, 'link' => '', 'type' => 'title');
$navigation = build_navigation($navlinks);
print_header_simple($streditingquiz, '', $navigation, "", "",
true, $strupdatemodule);
@ -329,9 +322,7 @@
$a->attemptnum = count_records('quiz_attempts', 'quiz', $quiz->id, 'preview', 0);
$a->studentnum = count_records_select('quiz_attempts', "quiz = '$quiz->id' AND preview = '0'", 'COUNT(DISTINCT userid)');
$a->studentstring = $course->students;
if (! $cm = get_coursemodule_from_instance("quiz", $quiz->instance, $course->id)) {
error("Course Module ID was incorrect");
}
echo "<div class=\"attemptsnotice\">\n";
echo "<a href=\"report.php?mode=overview&amp;id=$cm->id\">".get_string('numattempts', 'quiz', $a)."</a><br />".get_string("attemptsexist","quiz");
echo "</div><br />\n";
@ -347,15 +338,15 @@
}
// two column layout with quiz info in left column
$strupdatemodule = has_capability('moodle/course:manageactivities', $coursecontext)
$strupdatemodule = has_capability('moodle/course:manageactivities', $contexts->lowest())
? update_module_button($cm->id, $course->id, get_string('modulename', 'quiz'))
: "";
$navlinks = array();
$navlinks[] = array('name' => $strquizzes, 'link' => "index.php?id=$course->id", 'type' => 'activity');
$navlinks[] = array('name' => format_string($quiz->name), 'link' => "view.php?q=$quiz->instance", 'type' => 'activityinstance');
$navlinks[] = array('name' => $strquizzes, 'link' => "index.php?id=$course->id", 'type' => 'activity');
$navlinks[] = array('name' => format_string($quiz->name), 'link' => "view.php?q=$quiz->instance", 'type' => 'activityinstance');
$navlinks[] = array('name' => $streditingquiz, 'link' => '', 'type' => 'title');
$navigation = build_navigation($navlinks);
print_header_simple($streditingquiz, '', $navigation, "", "", true, $strupdatemodule);
$currenttab = 'edit';
@ -377,7 +368,7 @@
echo '</td><td style="width:50%" valign="top">';
question_showbank($thispageurl, $cm, $pagevars['qpage'], $pagevars['qperpage'], $pagevars['qsortorder'], $pagevars['qsortorderdecoded'],
question_showbank('editq', $contexts, $thispageurl, $cm, $pagevars['qpage'], $pagevars['qperpage'], $pagevars['qsortorder'], $pagevars['qsortorderdecoded'],
$pagevars['cat'], $pagevars['recurse'], $pagevars['showhidden'], $pagevars['showquestiontext']);
echo '</td></tr>';

View file

@ -141,6 +141,7 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true, $showbreak
$strgrade = get_string("grade");
$strremove = get_string('remove', 'quiz');
$stredit = get_string("edit");
$strview = get_string("view");
$straction = get_string("action");
$strmoveup = get_string("moveup");
$strmovedown = get_string("movedown");
@ -155,7 +156,7 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true, $showbreak
return 0;
}
if (!$questions = get_records_sql("SELECT q.*,c.course
if (!$questions = get_records_sql("SELECT q.*,c.contextid
FROM {$CFG->prefix}question q,
{$CFG->prefix}question_categories c
WHERE q.id in ($quiz->questions)
@ -169,7 +170,7 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true, $showbreak
$count = 0;
$qno = 1;
$sumgrade = 0;
$order = explode(",", $quiz->questions);
$order = explode(',', $quiz->questions);
$lastindex = count($order)-1;
// If the list does not end with a pagebreak then add it on.
if ($order[$lastindex] != 0) {
@ -235,12 +236,11 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true, $showbreak
echo '<td colspan="2">&nbsp;</td>';
}
$count++;
// missing </tr> here, if loop is broken, need to close the </tr> from line 199/201
// missing </tr> here, if loop is broken, need to close the </tr>
echo "</tr>";
continue;
}
$question = $questions[$qnum];
$canedit = has_capability('moodle/question:manage', get_context_instance(CONTEXT_COURSE, $question->course));
echo "<td>";
if ($count != 0) {
@ -276,17 +276,20 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete=true, $showbreak
}
echo '</td><td align="center">';
if ($question->qtype != 'random') {
quiz_question_preview_button($quiz, $question);
if (($question->qtype != 'random')){
echo quiz_question_preview_button($quiz, $question);
}
if ($canedit) {
$returnurl = $pageurl->out();
$questionparams = array('returnurl' => $returnurl, 'cmid'=>$quiz->cmid, 'id' => $qnum);
$questionurl = new moodle_url("$CFG->wwwroot/question/question.php", $questionparams);
$returnurl = $pageurl->out();
$questionparams = array('returnurl' => $returnurl, 'cmid'=>$quiz->cmid, 'id' => $question->id);
$questionurl = new moodle_url("$CFG->wwwroot/question/question.php", $questionparams);
if (question_has_capability_on($question, 'edit', $question->category) || question_has_capability_on($question, 'move', $question->category)) {
echo "<a title=\"$stredit\" href=\"".$questionurl->out()."\">
<img src=\"$CFG->pixpath/t/edit.gif\" class=\"iconsmall\" alt=\"$stredit\" /></a>";
} elseif (question_has_capability_on($question, 'view', $question->category)){
echo "<a title=\"$strview\" href=\"".$questionurl->out(false, array('id'=>$question->id))."\"><img
src=\"$CFG->pixpath/i/info.gif\" alt=\"$strview\" /></a>&nbsp;";
}
if ($allowdelete) {
if ($allowdelete && question_has_capability_on($question, 'use', $question->category)) { // remove from quiz, not question delete.
echo "<a title=\"$strremove\" href=\"".$pageurl->out_action(array('delete'=>$count))."\">
<img src=\"$CFG->pixpath/t/removeright.gif\" class=\"iconsmall\" alt=\"$strremove\" /></a>";
}

View file

@ -21,7 +21,8 @@
// Print the header
$strquizzes = get_string("modulenameplural", "quiz");
$streditquestions = '';
if (has_capability('moodle/question:manage', $coursecontext)) {
$editqcontexts = new question_edit_contexts($coursecontext);
if ($editqcontexts->have_one_edit_tab_cap('questions')) {
$streditquestions =
"<form target=\"_parent\" method=\"get\" action=\"$CFG->wwwroot/question/edit.php\">
<div>
@ -33,7 +34,7 @@
$navlinks = array();
$navlinks[] = array('name' => $strquizzes, 'link' => '', 'type' => 'activity');
$navigation = build_navigation($navlinks);
print_header_simple($strquizzes, '', $navigation,
'', '', true, $streditquestions, navmenu($course));

View file

@ -124,13 +124,13 @@ function quiz_delete_attempt($attempt, $quiz) {
return;
}
}
if ($attempt->quiz != $quiz->id) {
debugging("Trying to delete attempt $attempt->id which belongs to quiz $attempt->quiz " .
"but was passed quiz $quiz->id.");
return;
}
delete_records('quiz_attempts', 'id', $attempt->id);
delete_attempt($attempt->uniqueid);
@ -662,6 +662,9 @@ function quiz_upgrade_states($attempt) {
*/
function quiz_question_preview_button($quiz, $question) {
global $CFG;
if (!question_has_capability_on($question, 'use', $question->category)){
return '';
}
$strpreview = get_string('previewquestion', 'quiz');
return link_to_popup_window('/question/preview.php?id=' . $question->id . '&amp;quizid=' . $quiz->id, 'questionpreview',
"<img src=\"$CFG->pixpath/t/preview.gif\" class=\"iconsmall\" alt=\"$strpreview\" />",

View file

@ -16,12 +16,13 @@ if (!isset($currenttab)) {
if (!isset($cm)) {
$cm = get_coursemodule_from_instance('quiz', $quiz->id);
}
if (!isset($course)) {
$course = get_record('course', 'id', $quiz->course);
}
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
if (!isset($contexts)){
$contexts = new question_edit_contexts($context);
}
$tabs = array();
$row = array();
$inactive = array();
@ -36,7 +37,7 @@ if (has_capability('mod/quiz:viewreports', $context)) {
if (has_capability('mod/quiz:preview', $context)) {
$row[] = new tabobject('preview', "$CFG->wwwroot/mod/quiz/attempt.php?q=$quiz->id", get_string('preview', 'quiz'));
}
if (has_capability('mod/quiz:manage', $context)) {
if ($contexts->have_one_edit_tab_cap('editq')) {
$row[] = new tabobject('edit', "$CFG->wwwroot/mod/quiz/edit.php?cmid=$cm->id", get_string('edit'));
}
@ -83,9 +84,12 @@ if ($currenttab == 'edit' and isset($mode)) {
$streditingquiz = get_string("editinga", "moodle", $strquiz);
$strupdate = get_string('updatethis', 'moodle', $strquiz);
$row[] = new tabobject('editq', "$CFG->wwwroot/mod/quiz/edit.php?".$thispageurl->get_query_string(), $strquiz, $streditingquiz);
questionbank_navigation_tabs($row, $context, $thispageurl->get_query_string());
if ($contexts->have_one_edit_tab_cap('editq')) {
$row[] = new tabobject('editq', "$CFG->wwwroot/mod/quiz/edit.php?".$thispageurl->get_query_string(), $strquiz, $streditingquiz);
}
questionbank_navigation_tabs($row, $contexts, $thispageurl->get_query_string());
$tabs[] = $row;
}
print_tabs($tabs, $currenttab, $inactive, $activated);