Index: quiz.install =================================================================== --- quiz.install (revision 5630) +++ quiz.install (working copy) @@ -8,6 +8,17 @@ */ /** + * Implementation of hook_update_N() + * + * Adding a field to turn on/off showing all question on one page + */ +function quiz_update_6419() { + $result = array(); + db_add_field($result, 'quiz_node_properties', 'single_page', array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0)); + return $result; +} + +/** * Implementation of hook_update_N * * Change the primary key of the quiz_node_properties table to something more useful... @@ -876,6 +887,12 @@ 'not null' => TRUE, 'default' => 0, ), + 'single_page' => array( + 'type' => 'int', + 'size' => 'small', + 'not null' => TRUE, + 'default' => 0, + ), ), 'primary key' => array('vid'), // 'unique keys' => array('vid'), Index: quiz.pages.inc =================================================================== --- quiz.pages.inc (revision 5630) +++ quiz.pages.inc (working copy) @@ -449,17 +449,27 @@ } /** - * Theme the single question node + * Theme the single or multi question node. * * @param $node * The question node * @return * Themed html feedback */ -function theme_quiz_single_question_node($node) { - // This might seem meaningless, but it is designed this way to allow themes to add more - // meaningful stuff here... - return $node->body; +function theme_quiz_single_question_node($nodes) { + if (is_array($nodes)) { + foreach ($nodes as $node) { + preg_match('|]*?>(.*?)|si', $node->body, $matches); + $form_free_body = preg_replace('/]*?>/','',$matches[1]); + $nodes_output .= '
  • ' . str_replace('name="tries', 'name="tries_' . $node->nid . '', $form_free_body) . '
  • '; + } + $output = '
      ' . $nodes_output . '
    '; + return $output; + } + else { + $node = $nodes; + return $node->body; + } } /** Index: quiz.module =================================================================== --- quiz.module (revision 5630) +++ quiz.module (working copy) @@ -535,12 +535,12 @@ backwards_navigation, repeat_until_correct, quiz_open, quiz_close, takes, show_attempt_stats, keep_results, time_limit, pass_rate, summary_pass, summary_default, quiz_always, feedback_time, display_feedback, tid, - has_userpoints, allow_skipping) + has_userpoints, allow_skipping, single_page) VALUES(%d, %d, '%s', %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, '%s', '%s', %d, %d, %d, %d, - %d, %d)"; + %d, %d, %d)"; // If the quiz is saved as not randomized we have to make sure that questions belonging to the quiz are saved as not random _quiz_check_num_random($node); @@ -549,7 +549,7 @@ $node->backwards_navigation, $node->repeat_until_correct, $node->quiz_open, $node->quiz_close, $node->takes, $node->show_attempt_stats, $node->keep_results, $node->time_limit, $node->pass_rate, $node->summary_pass, $node->summary_default, $node->quiz_always, $node->feedback_time, $node->display_feedback, $tid, - isset($node->has_userpoints) ? $node->has_userpoints : 0, $node->allow_skipping); + isset($node->has_userpoints) ? $node->has_userpoints : 0, $node->allow_skipping, $node->single_page); _quiz_insert_resultoptions($node); @@ -610,13 +610,14 @@ display_feedback = %d, number_of_random_questions = %d, has_userpoints = %d, - allow_skipping = %d + allow_skipping = %d, + single_page = %d WHERE vid = %d AND nid = %d"; _quiz_check_num_random($node); $resource = db_query($sql, $node->vid, $node->aid, $node->randomization, $node->backwards_navigation, $node->repeat_until_correct, $node->quiz_open, $node->quiz_close, $node->takes, $node->show_attempt_stats, $node->keep_results, $node->time_limit, $node->pass_rate, $node->summary_pass, $node->summary_default, $node->quiz_always, - $node->feedback_time, $node->display_feedback, $node->number_of_random_questions, isset($node->has_userpoints) ? $node->has_userpoints : 0, $node->allow_skipping, + $node->feedback_time, $node->display_feedback, $node->number_of_random_questions, isset($node->has_userpoints) ? $node->has_userpoints : 0, $node->allow_skipping, $node->single_page, $node->vid, $node->nid); _quiz_update_resultoptions($node); } @@ -689,6 +690,7 @@ 'tid' => 0, 'has_userpoints' => 0, 'allow_skipping' => 1, + 'single_page' => 0, ); } @@ -863,6 +865,12 @@ '#default_value' => $node->allow_skipping, '#description' => t('Whether to allow users to skip questions in the @quiz', array('@quiz' => QUIZ_NAME)), ); + $form['taking']['single_page'] = array( + '#type' => 'checkbox', + '#title' => t('Show all questions on a single page'), + '#default_value' => $node->single_page, + '#description' => t('Whether to show all questions on a single page in the @quiz', array('@quiz' => QUIZ_NAME)), + ); $form['taking']['backwards_navigation'] = array( '#type' => 'checkbox', '#title' => t('Backwards navigation'), @@ -1493,6 +1501,9 @@ function quiz_take_quiz($quiz) { global $user; $allow_skipping = $quiz->allow_skipping; + if ($quiz->single_page) { + $_POST['tries'] == '1'; + } if (!isset($quiz)) { drupal_not_found(); @@ -1512,7 +1523,7 @@ } // If the session has no data for this quiz. - if (!isset($_SESSION['quiz_'. $quiz->nid]['quiz_questions'])) { + if ($quiz->single_page || !isset($_SESSION['quiz_'. $quiz->nid]['quiz_questions'])) { // We delete questions in progress from old revisions. _quiz_delete_old_in_progress($quiz, $user->uid); @@ -1549,6 +1560,7 @@ $_SESSION['quiz_'. $quiz->nid]['question_start_time'] = time(); $_SESSION['quiz_'. $quiz->nid]['question_duration'] = $quiz->time_limit; $_SESSION['quiz_'. $quiz->nid]['quiz_vid'] = $quiz->vid; + $_SESSION['current_quiz_id'] = $quiz->nid; } else { @@ -1579,15 +1591,37 @@ $_SESSION['quiz_'. $quiz->nid]['quiz_questions'][0]['rid'] = $_SESSION['quiz_' . $quiz->nid]['result_id']; $_SESSION['quiz_'. $quiz->nid]['previous_quiz_questions'][] = $_SESSION['quiz_'. $quiz->nid]['quiz_questions'][0]; $former_question_array = array_shift($_SESSION['quiz_'. $quiz->nid]['quiz_questions']); - $former_question = node_load($former_question_array['nid'], $former_question_array['vid']); + if (!$quiz->single_page) { + $former_question = node_load($former_question_array['nid'], $former_question_array['vid']); - // Call hook_evaluate_question(). - $types = _quiz_get_question_types(); - $module = $types[$former_question->type]['module']; - $result = module_invoke($module, 'evaluate_question', $former_question, $_SESSION['quiz_'. $quiz->nid]['result_id']); - $q_passed_validation = $result->is_valid; - quiz_store_question_result($quiz, $result, array('set_msg' => TRUE)); + // Call hook_evaluate_question() for a single question. + $types = _quiz_get_question_types(); + $module = $types[$former_question->type]['module']; + $result = module_invoke($module, 'evaluate_question', $former_question, $_SESSION['quiz_'. $quiz->nid]['result_id']); + $q_passed_validation = $result->is_valid; + quiz_store_question_result($quiz, $result, array('set_msg' => TRUE)); + } + else { + foreach ($questions as $question) { + $former_question = node_load($question['nid'], $question['vid']); + $_POST['tries'] = $_POST['tries_' . $question['nid']]; + // Call hook_evaluate_question() for each question. + $types = _quiz_get_question_types(); + $module = $types[$former_question->type]['module']; + $result = module_invoke($module, 'evaluate_question', $former_question, $_SESSION['quiz_'. $quiz->nid]['result_id']); + $q_passed_validation = $result->is_valid; + if ($q_passed_validation != 1) { + /** Very basic validation. TODO: save form values. */ + drupal_set_message('Please check your submission for errors.','error'); + quiz_delete_results(array($_SESSION['quiz_'. $quiz->nid]['result_id'])); + drupal_goto("node/{$quiz->nid}/take"); + } + quiz_store_question_result($quiz, $result, array('set_msg' => TRUE)); + } + $quiz_end = TRUE; + } + // Stash feedback in the session, since the $_POST gets cleared. if ($quiz->feedback_time == QUIZ_FEEDBACK_QUESTION && $_POST['op'] != t('Back') && $q_passed_validation === TRUE) { // Invoke hook_get_report(). @@ -1649,6 +1683,12 @@ $_SESSION['quiz_'. $quiz->nid]['quiz_questions'][0]['nid'], $_SESSION['quiz_'. $quiz->nid]['quiz_questions'][0]['vid'] ); + if ($quiz->single_page) { + $question_node_multi = array(); + foreach($questions as $question) { + array_push($question_node_multi,node_load($question['nid'], $question['vid'])); + } + } if (isset($_SESSION['quiz_'. $quiz->nid]['quiz_questions'][0]['rid'])) $question_node->rid = $_SESSION['quiz_'. $quiz->nid]['quiz_questions'][0]['rid']; // We got an error message when trying to validate the previous answer @@ -1733,7 +1773,12 @@ } // If we're not yet at the end. if (empty($quiz_end)) { - $content['body']['question']['#value'] = quiz_take_question_view($question_node, $quiz); + if (!$quiz->single_page) { + $content['body']['question']['#value'] = quiz_take_question_view($question_node, $quiz); + } + else { + $content['body']['question']['#value'] = quiz_node_view_multi($question_node_multi, TRUE, FALSE); + } $content['body']['question']['#weight'] = 0; // If we had feedback from the last question. if (isset($_SESSION['quiz_'. $quiz->nid]['feedback']) && $quiz->feedback_time == QUIZ_FEEDBACK_QUESTION) { @@ -1775,6 +1820,15 @@ return $content; } +function quiz_node_view_multi($question_nodes = array()) { + foreach($question_nodes as &$question_node) { + $question_node = node_build_content($question_node, FALSE, TRUE); + node_invoke_nodeapi($question_node, 'alter', FALSE, TRUE); + $question_node->body = drupal_render($question_node->content); + } + return theme('quiz_single_question_node', $question_nodes); +} + /** * Create the view for a question the user is about to take. *