Insight | Nov 13, 2015
Customizing the Quiz Module for Every Need in Drupal
By Josh Fremer
The Drupal Quiz module provides a great foundation to build scored assessments in Drupal. It offers a range of scoring customizations, but it can't fill every need out of the box.
Fortunately, Quiz also offers robust API exposed through a collection of hooks. If you have custom logic that impacts your scoring, hook_quiz_finished is for you. This hook allows you to modify any properties of a quiz result when it's saved.
In my case, I had the requirement that any questions answered "N/A" should be subtracted from the denominator of the scoring equation. So, for instance, if a quiz had 10 questions and had 1 correct answer, 1 incorrect answer and 8 "N/A", the quiz score would be 50% (1/2).
/** * Implements hook_quiz_finished(). * * If a question is answered "N/A", that question doesn't count toward the total * possible score. */ function mymodule_quiz_finished($quiz, $score, $data) { $possible_score = $score['possible_score']; // Here we're going to count up the number of 'N/A' answers. $query = db_select('quiz_node_results_answers', 'qra'); $query->join('quiz_multichoice_user_answers', 'qmua', 'qra.result_answer_id = qmua.result_answer_id'); $query->join('quiz_multichoice_user_answer_multi', 'qmuam', 'qmua.id = qmuam.user_answer_id'); $query->join('quiz_multichoice_answers', 'qma', 'qmuam.answer_id = qma.id'); $query->condition('qra.result_id', $data['result_id']); $query->condition('qma.answer', t('N/A')); $query->fields('qra', array('result_answer_id')); $na_answers = $query->execute()->rowCount(); // Subtract the total from the highest possible score. $possible_score = $possible_score - $na_answers; // Then recalculate the score. $quiz_result = quiz_result_load($data['result_id']); if ($possible_score > 0) { $quiz_result->score = ($score['numeric_score'] / $possible_score) * 100; } else { $quiz_result->score = 0; } entity_save('quiz_result', $quiz_result); }
hook_quiz_finished implementations take three arguments:
- The quiz entity for which a new result was recorded.
- An associative array of scoring data, including
possible_score
(the number of total questions encountered) andnumeric_score
(the number of correct answers). - An associative array of information about the quiz result record, including
result_id
which you can use to load the full result entity for updating.
In my example above I query for a count of all "N/A" answers recorded for the quiz result in question (this takes a few joins). Then I simply subtract that count from the number of possible answers and re-calculate the score. As far as the Drupal Quiz module is concerned, scoring is finished for this result; it never goes back and re-calculates so your custom-calculated score is safe and ready for display.
Drop us a line
Have a project in mind?
Contacting Third and Grove may cause awesomeness. Side effects include a website too good to ignore. Proceed at your own risk.