You are here

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;
}