function quiz_update_6401 in Quiz 6.4
Implementation of hook_update_N()
Add a field to store max score for each question in a quiz. Also store the total max score in the quiz_node_properties table
This function uses the batch feature
File
- ./
quiz.install, line 550 - Quiz install schema for installing the quiz module
Code
function quiz_update_6401(&$sandbox = NULL) {
$result = array();
// Altering tables:
if (!isset($sandbox['tables_changed'])) {
db_add_field($result, 'quiz_node_relationship', 'max_score', array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
));
db_add_field($result, 'quiz_node_properties', 'max_score', array(
'type' => 'int',
'not null' => TRUE,
'default' => 0,
));
// THIS IS UGLY! But it needs to be installed here because we don't know in what order the updater
// Will execute the update hooks...
if (!db_table_exists('quiz_question_properties')) {
db_create_table($result, 'quiz_question_properties', array(
'fields' => array(
'nid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'vid' => array(
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
),
'max_score' => array(
'type' => 'int',
'unsigned' => TRUE,
'default' => 0,
),
),
'primary key' => array(
'nid',
'vid',
),
));
}
$sandbox['tables_changed'] = TRUE;
$sandbox['progress'] = 0;
// Updating max_score for all question types
// Creating array with all question types and relevant tables
$sandbox['question_types'] = array(
'long_answer' => array(
'node_properties',
),
'matching' => array(
'node',
),
'multichoice' => array(
'properties',
'answers',
),
'scale' => array(
'node_properties',
),
'short_answer' => array(
'node_properties',
),
'truefalse' => array(
'node',
),
);
// Removing questiontypes that aren't in use
foreach ($sandbox['question_types'] as $type => $tables) {
$tables_exists = TRUE;
$pre = 'quiz_' . $type . '_';
foreach ($tables as $table) {
if (!db_table_exists($pre . $table)) {
$tables_exists = FALSE;
}
}
if (!$tables_exists) {
unset($sandbox['question_types'][$type]);
}
}
$sandbox['max'] = count($sandbox['question_types']) + 4;
}
// Doing convertion for one questiontype at a time as a batch process
if ($current_type = array_pop(array_keys($sandbox['question_types']))) {
$tables = array_pop($sandbox['question_types']);
switch ($current_type) {
case 'long_answer':
$sql = 'INSERT INTO {quiz_question_properties}
(nid, vid, max_score)
SELECT t.nid, t.vid, t.maximum_score
FROM {quiz_long_answer_node_properties} t';
$result[] = update_sql($sql);
db_drop_field($result, 'quiz_long_answer_node_properties', 'maximum_score');
break;
case 'matching':
$sql = 'INSERT INTO {quiz_question_properties}
(nid, vid, max_score)
SELECT t.nid, t.vid, COUNT(*)
FROM {quiz_matching_node} t
GROUP BY t.nid, t.vid';
$result[] = update_sql($sql);
break;
case 'multichoice':
$sql = 'INSERT INTO {quiz_question_properties}
(nid, vid, max_score)
SELECT t.nid, t.vid, 1
FROM {quiz_multichoice_properties} t
WHERE t.choice_boolean = 1';
$result[] = update_sql($sql);
$sql = 'INSERT INTO {quiz_question_properties}
(nid, vid)
SELECT t.nid, t.vid
FROM {quiz_multichoice_properties} t
WHERE t.choice_boolean = 0';
$result[] = update_sql($sql);
$sql = 'UPDATE {quiz_question_properties} p
JOIN {quiz_multichoice_properties} mp
ON p.nid = mp.nid AND p.vid = mp.vid
SET max_score = (
SELECT COUNT(max_score)
FROM (
SELECT if(a.score_if_chosen > a.score_if_not_chosen, a.score_if_chosen,
a.score_if_not_chosen) AS max_score, question_nid, question_vid
FROM {quiz_multichoice_answers} a
) AS ma
WHERE ma.question_nid = p.nid AND ma.question_vid = p.vid
GROUP BY ma.question_nid, ma.question_vid
)
WHERE mp.choice_boolean = 0';
$result[] = update_sql($sql);
break;
case 'scale':
$sql = 'INSERT INTO {quiz_question_properties}
(nid, vid)
SELECT t.nid, t.vid
FROM {quiz_scale_node_properties} t';
$result[] = update_sql($sql);
break;
case 'short_answer':
$sql = 'INSERT INTO {quiz_question_properties}
(nid, vid, max_score)
SELECT t.nid, t.vid, t.maximum_score
FROM {quiz_short_answer_node_properties} t';
$result[] = update_sql($sql);
db_drop_field($result, 'quiz_short_answer_node_properties', 'maximum_score');
break;
case 'truefalse':
$sql = 'INSERT INTO {quiz_question_properties}
(nid, vid, max_score)
SELECT t.nid, t.vid, 1
FROM {quiz_truefalse_node} t';
$result[] = update_sql($sql);
break;
}
$sandbox['progress']++;
}
else {
if (!isset($sandbox['quiz_directions_done'])) {
$sql = 'INSERT INTO {quiz_question_properties}
(nid, vid, max_score)
SELECT n.nid, n.vid, 0
FROM {node} n
WHERE type = "quiz_directions"';
$result[] = update_sql($sql);
$sandbox['quiz_directions_done'] = TRUE;
}
elseif (!isset($sandbox['quiz_relationships_done'])) {
$sql = 'UPDATE {quiz_node_relationship} r
JOIN {quiz_question_properties} p
ON r.child_nid = p.nid AND r.child_vid = p.vid
SET r.max_score = p.max_score';
$result[] = update_sql($sql);
$sandbox['quiz_relationships_done'] = TRUE;
}
elseif (!isset($sandbox['matching_relationship_done'])) {
$sql = 'UPDATE {quiz_node_relationship} r
JOIN {node} n
ON r.child_nid = n.nid AND r.child_vid = n.vid
SET r.max_score = 1
WHERE n.type = "matching"';
$result[] = update_sql($sql);
$sandbox['matching_relationship_done'] = TRUE;
}
elseif (!isset($sandbox['quiz_properties_done'])) {
$sql = 'UPDATE {quiz_node_properties} p
SET p.max_score =
(SELECT SUM(r.max_score)
FROM {quiz_node_relationship} r
WHERE r.parent_nid = p.nid AND r.parent_vid = p.vid
GROUP BY r.parent_nid, r.parent_vid)';
$result[] = update_sql($sql);
$sandbox['quiz_properties_done'] = TRUE;
}
$sandbox['progress']++;
}
$result['#finished'] = $sandbox['progress'] / $sandbox['max'];
return $result;
}