diff --git a/quiz.module b/quiz.module index 065af8b..132be03 100644 --- a/quiz.module +++ b/quiz.module @@ -999,8 +999,8 @@ function quiz_view($node) { '#weight' => -1, ); - $available = quiz_availability($node); - if ($available === TRUE) { + $available = quiz_access('take', $node); + if ($available['success']) { // Check the permission before displaying start button. if (user_access('access quiz')) { // Add a link to the take tab. @@ -1012,7 +1012,7 @@ function quiz_view($node) { } else { $node->content['take'] = array( - '#markup' => '
' . $available . '
', + '#markup' => '
' . $available['message'] . '
', '#weight' => 2, ); } @@ -1036,7 +1036,8 @@ function quiz_take_page($quiz) { drupal_goto("node/{$quiz_result->nid}/take/" . ($_SESSION['quiz'][$quiz_result->nid]['current'])); } else { - if (quiz_start_check($quiz)) { + $result = quiz_access('take', $quiz); + if ($result['success']) { $quiz_result = entity_create('quiz_result', array( 'nid' => $quiz->nid, 'vid' => $quiz->vid, @@ -1045,7 +1046,7 @@ function quiz_take_page($quiz) { )); } else { - return array('body' => array('#markup' => t('This @quiz is not available.', array('@quiz' => QUIZ_NAME)))); + return array('body' => array('#markup' => $result['message'])); } } @@ -1078,7 +1079,8 @@ function quiz_take_access($node) { if ($node->type != 'quiz') { return FALSE; } - return node_access('view', $node) && user_access('access quiz') && quiz_availability($node) === TRUE; + $result = quiz_access('take', $node); + return node_access('view', $node) && user_access('access quiz') && $result['success']; } /** @@ -2189,53 +2191,99 @@ function quiz_is_passed($uid, $nid, $vid) { } /** - * Actions to take place at the start of a quiz. - * - * This should only be checked when the user does not yet have an active - * attempt. - * - * @param $quiz - * The quiz node. - * - * @return bool - * FALSE if there is an error. + * Can a user take this quiz? */ -function quiz_start_check($quiz) { - global $user; +function quiz_quiz_access($op = 'take', $quiz, $account) { + $hooks = array(); $user_is_admin = node_access('update', $quiz); + // Make sure this is available. + if ($quiz->quiz_always != 1) { + // Compare current GMT time to the open and close dates (which should still + // be in GMT time). + + $quiz_open = REQUEST_TIME >= $quiz->quiz_open; + $quiz_closed = REQUEST_TIME >= $quiz->quiz_close; + if (!$quiz_open || $quiz_closed) { + if ($user_is_admin) { + $hooks[] = array( + 'owner_limit' => array( + 'success' => TRUE, + 'message' => t('You are marked as an administrator or owner for this @quiz. While you can take this @quiz, the open/close times prohibit other users from taking this @quiz.', array('@quiz' => QUIZ_NAME)), + ), + ); + } + else { + + if ($quiz_closed) { + $hooks[] = array( + 'owner_limit' => array( + 'success' => TRUE, + 'message' => t('This @quiz is closed.', array('@quiz' => QUIZ_NAME)), + ), + ); + } + if (!$quiz_open) { + $hooks[] = array( + 'owner_limit' => array( + 'success' => TRUE, + 'message' => t('This @quiz is not yet open.', array('@quiz' => QUIZ_NAME)), + ), + ); + } + } + } + } + // Check to see if this user is allowed to take the quiz again: if ($quiz->takes > 0) { - $taken = db_query("SELECT COUNT(*) AS takes FROM {quiz_node_results} WHERE uid = :uid AND nid = :nid", array(':uid' => $user->uid, ':nid' => $quiz->nid))->fetchField(); + $taken = db_query("SELECT COUNT(*) AS takes FROM {quiz_node_results} WHERE uid = :uid AND nid = :nid", array(':uid' => $account->uid, ':nid' => $quiz->nid))->fetchField(); $allowed_times = format_plural($quiz->takes, '1 time', '@count times'); $taken_times = format_plural($taken, '1 time', '@count times'); // The user has already taken this quiz. if ($taken) { if ($user_is_admin) { - - drupal_set_message(t('You have taken this @quiz already. You are marked as an owner or administrator for this quiz, so you can take this quiz as many times as you would like.', array('@quiz' => QUIZ_NAME)), 'status'); + $hooks[] = array( + 'owner_limit' => array( + 'success' => TRUE, + 'message' => t('You have taken this @quiz already. You are marked as an owner or administrator for this quiz, so you can take this quiz as many times as you would like.', array('@quiz' => QUIZ_NAME)), + ), + ); } // If the user has already taken this quiz too many times, stop the user. elseif ($taken >= $quiz->takes) { - drupal_set_message(t('You have already taken this @quiz @really. You may not take it again.', array('@quiz' => QUIZ_NAME, '@really' => $taken_times)), 'error'); - return FALSE; + $hooks[] = array( + 'attempt_limit' => array( + 'success' => FALSE, + 'message' => t('You have already taken this @quiz @really. You may not take it again.', array('@quiz' => QUIZ_NAME, '@really' => $taken_times)), + ), + ); } // If the user has taken the quiz more than once, see if we should report // this. elseif ($quiz->show_attempt_stats) { - drupal_set_message(t("You can only take this @quiz @allowed. You have taken it @really.", array('@quiz' => QUIZ_NAME, '@allowed' => $allowed_times, '@really' => $taken_times)), 'status'); + $hooks[] = array( + 'attempt_limit' => array( + 'success' => TRUE, + 'message' => t("You can only take this @quiz @allowed. You have taken it @really.", array('@quiz' => QUIZ_NAME, '@allowed' => $allowed_times, '@really' => $taken_times)), 'status'), + ); } } } // Check to see if the user is registered, and user alredy passed this quiz. - if ($quiz->show_passed && $user->uid && quiz_is_passed($user->uid, $quiz->nid, $quiz->vid)) { - drupal_set_message(t('You have already passed this @quiz.', array('@quiz' => QUIZ_NAME)), 'status', FALSE); + if ($quiz->show_passed && $user->uid && quiz_is_passed($account->uid, $quiz->nid, $quiz->vid)) { + $hooks[] = array( + 'already_passed' => array( + 'success' => TRUE, + 'message' => t('You have already passed this @quiz.', array('@quiz' => QUIZ_NAME)), + ), + ); } - return TRUE; + return $hooks; } /** @@ -2243,43 +2291,23 @@ function quiz_start_check($quiz) { * * @param $quiz * The quiz node - * @return - * TRUE if available - * Error message(String) if not available + * + * @return array + * An array keyed with: 'success' and 'message' */ -function quiz_availability($quiz) { - global $user; - - $user_is_admin = user_access('edit any quiz content') || (user_access('edit own quiz content') && $quiz->uid == $user->uid); - if ($user_is_admin || $quiz->quiz_always == 1) { - return TRUE; +function quiz_access($op = 'take', $quiz, $account = NULL) { + if (!$account) { + global $user; + $account = $user; } - // Make sure this is available. - if ($quiz->quiz_always != 1) { - // Compare current GMT time to the open and close dates (which should still - // be in GMT time). - - $quiz_open = REQUEST_TIME >= $quiz->quiz_open; - $quiz_closed = REQUEST_TIME >= $quiz->quiz_close; - if (!$quiz_open || $quiz_closed) { - if ($user_is_admin) { - return t('You are marked as an administrator or owner for this @quiz. While you can take this @quiz, the open/close times prohibit other users from taking this @quiz.', array('@quiz' => QUIZ_NAME)); - } - - if ($quiz_closed) { - return t('This @quiz is closed.', array('@quiz' => QUIZ_NAME)); - } - if (!$quiz_open) { - return t('This @quiz is not yet open.', array('@quiz' => QUIZ_NAME)); - } + $hooks = module_invoke_all('quiz_access', $op, $quiz, $account); - // Can't take quiz. - return FALSE; + foreach ($hooks as $hook) { + if (!$hook['success']) { + return $hook; } } - - return TRUE; } /**