/**
     * Shows the quiz for the unit, based on the type being shown.
     * 
     * @param Boolean $showErrorsOnForm If true, show the errors on the form, acts as an override to disable showing errors if they are not wanted.
     * 
     * @return String The HTML that renders the quiz for answering.
     */
    function render_quizzes_handleQuizRendering($showErrorsOnForm = true)
    {
        // Hopefully not needed, but just in case.
        if (!$this->unitQuizDetails) {
            return false;
        }
        // Reload all raw answers user has created so far (if we have anything so far)
        if (!empty($this->unitQuizProgress) && 'incomplete' == $this->unitQuizProgress->quiz_paging_status) {
            $this->fetch_quizzes_loadRawAnswersSoFarForThisQuiz($this->unitQuizProgress->quiz_data);
        }
        // Render the wrapper for the quiz using the pending message section
        // Use the Quiz ID and Unit ID to validate permissions.
        $html = sprintf('<div class="wpcw_fe_quiz_box_wrap" id="wpcw_fe_quiz_complete_%d_%d">', $this->unitPost->ID, $this->unitQuizDetails->quiz_id);
        // Are we going to show the answers on a single for as part of the review?
        if ($this->check_paging_shouldWeShowReviewPage_rightNow()) {
            // To do, show a message here about reviewing answers...
            $html .= WPCW_UnitFrontend::message_createMessage_warning(__('You can now review your answers before submitting them.', 'wp_courseware'));
        }
        // Use any raw selection data that we have so far to pre-fill answers.
        $resultsList = $this->unchecked_QuizAnswersToGrade;
        // enctype="multipart/form-data" for file uploads..
        // data-wpcw_expired="false" - this is used by the timer to indicate if the timer has expired or not.
        $html .= sprintf('<form method="post" enctype="multipart/form-data" id="quiz_complete_%d_%d" data-wpcw_unit="%d" data-wpcw_quiz="%d" data-wpcw_expired="false">', $this->unitPost->ID, $this->unitQuizDetails->quiz_id, $this->unitPost->ID, $this->unitQuizDetails->quiz_id);
        $html .= '<div class="wpcw_fe_quiz_box wpcw_fe_quiz_box_pending">';
        // #### 1 - Quiz Title - constant for all quizzes
        $html .= sprintf('<div class="wpcw_fe_quiz_title">%s</div>', $this->unitQuizDetails->quiz_title);
        // #### 2 - Pass mark - just needed for blocking quizes
        if ('quiz_block' == $this->unitQuizDetails->quiz_type) {
            $totalQs = count($this->unitQuizDetails->questions);
            $passQs = ceil($this->unitQuizDetails->quiz_pass_mark / 100 * $totalQs);
            $html .= '<div class="wpcw_fe_quiz_pass_mark">';
            $html .= sprintf(__('You\'ll need to correctly answer at least <b>%d of the %d</b> questions below (<b>at least %d%%</b>) to progress to the next unit.', 'wp_courseware'), $passQs, $totalQs, $this->unitQuizDetails->quiz_pass_mark);
            $html .= '</div>';
        }
        // #### 3 - The actual question form.
        if (!empty($this->unitQuizDetails->questions)) {
            $questionNum = 1;
            $showQuestions = true;
            // Timer Mode
            if ('use_timer' == $this->unitQuizDetails->quiz_timer_mode) {
                // We've not started the quiz yet, so we show the begin test button.
                if (empty($this->unitQuizProgress) || 'retake_waiting' == $this->unitQuizProgress->quiz_next_step_type) {
                    $showQuestions = false;
                    $html .= '<div class="wpcw_fe_quiz_q_hdr"></div>';
                    // Begin Quiz
                    $html .= sprintf('
									<div class="wpcw_fe_quiz_begin_quiz">
										<div class="wpcw_fe_quiz_begin_quiz_hdr">%s</div>
										<a href="#" class="fe_btn fe_btn_completion" id="wpcw_fe_quiz_begin_quiz" data-wpcw_quiz="%d" data-wpcw_unit="%d" >%s</a>
										
										<div class="wpcw_fe_submit_loader wpcw_loader">
											<img src="%simg/ajax_loader.gif" />
										</div>
									</div>', sprintf(__('You have <b>%s</b> to complete this quiz...', 'wp_coursware'), WPCW_time_convertMinutesToHumanLabel($this->unitQuizDetails->quiz_timer_mode_limit)), $this->unitQuizDetails->quiz_id, $this->unitPost->ID, __('Begin Quiz...', 'wp_courseware'), WPCW_plugin_getPluginPath());
                } else {
                    // Total time in seconds for this quiz
                    $timerDetails_secondsLeft = $allowedTime = 60 * $this->unitQuizDetails->quiz_timer_mode_limit;
                    // What time do we have left?
                    $timeSoFar = strtotime($this->unitQuizProgress->quiz_started_date);
                    $timeNow = current_time('timestamp');
                    // We've started the quiz when the time so far is > 0
                    if ($timeSoFar > 0) {
                        $timerDetails_secondsLeft = $allowedTime - ($timeNow - $timeSoFar);
                    }
                    // Show the timer if we have time left.
                    $html .= sprintf('<div id="wpcw_fe_timer_countdown" data-time_left="%d">%s</div>', $timerDetails_secondsLeft, WPCW_time_convertSecondsToHumanLabel($timerDetails_secondsLeft));
                }
            }
            if ($showQuestions) {
                // We're paging, so check what question or questions to show next.
                if ($this->check_paging_areWePagingQuestions()) {
                    // Stores the index of the next question to show
                    $questionToShowIndex = $this->fetch_paging_getQuestionIndex();
                    $question = $this->fetch_paging_getQuestion($questionToShowIndex);
                    // Show progress of user through the questions.
                    $html .= sprintf('<div class="wpcw_fe_paging_progress">%s</div>', sprintf(__('Question %d of %d', 'wp_courseware'), $questionToShowIndex + 1, $this->fetch_paging_getQuestionCount()));
                    // Header before questions (but show progress before the header line).
                    $html .= '<div class="wpcw_fe_quiz_q_hdr"></div>';
                    // Show the answer later button.
                    if ($this->check_paging_shouldWeShowAnswerLaterButton()) {
                        $html .= sprintf('<div class="wpcw_fe_quiz_answer_later"><a href="#" class="fe_btn fe_btn_small fe_btn_navigation" id="wpcw_fe_quiz_answer_later">%s</a></div>', __('Answer Later...', 'wp_courseware'));
                    }
                    // Render just this question
                    $html .= $this->render_quizzes_handleQuizRendering_singleQuestion($question, $resultsList, $showErrorsOnForm, $questionToShowIndex + 1, true, 0);
                    // Work out what caption to show for the submit button. Change this if we're about to
                    // submit the answers for the final question or review our answers.
                    $buttonCaption = __('Save &amp; Next Question &raquo;', 'wp_courseware');
                    // Are we showing the last incomplete question (and we're nearly complete)
                    if ($this->unitQuizProgress && $this->unitQuizProgress->quiz_paging_incomplete <= 1 && $this->check_paging_isThisTheLastIncompleteQuestion($question->question_id)) {
                        // We appear to be on the last question. Are we going to review too?
                        if ($this->check_paging_shouldWeShowReviewPage()) {
                            $buttonCaption = __('Save &amp; Review Answers &raquo;', 'wp_courseware');
                        } else {
                            $buttonCaption = __('Submit Answers', 'wp_courseware');
                        }
                    }
                    // Previous button - created if required. Using a button rather than a link to ensure the buttons look right when side-by-side.
                    $buttonPreviousClicker = false;
                    if ($this->check_paging_shouldWeShowPreviousButton()) {
                        $buttonPreviousClicker = sprintf('<input type="submit" class="fe_btn fe_btn_completion btn_completion" id="fe_btn_quiz_previous" name="previous_question" value="%s">', __('&laquo; Previous Question', 'wp_courseware'));
                    }
                    // #### 4A - The navigation buttons
                    $html .= sprintf('<div class="wpcw_fe_quiz_submit wpcw_fe_quiz_submit_data">				
										%s								    
										<div class="wpcw_fe_submit_loader wpcw_loader">
											<img src="%simg/ajax_loader.gif" />
										</div>									
										%s						
										<input type="submit" class="fe_btn fe_btn_completion btn_completion" id="fe_btn_quiz_next" name="submit" value="%s">
									</div>', WPCW_content_progressBar(0, 'wpcw_fe_upload_progress'), WPCW_plugin_getPluginPath(), $buttonPreviousClicker, $buttonCaption);
                } else {
                    // Header before questions
                    $html .= '<div class="wpcw_fe_quiz_q_hdr"></div>';
                    $questionIndex = 0;
                    foreach ($this->unitQuizDetails->questions as $question) {
                        $html .= $this->render_quizzes_handleQuizRendering_singleQuestion($question, $resultsList, $showErrorsOnForm, $questionNum++, false, $questionIndex++);
                    }
                    // #### 4B - The submit answers button. //<a href="#" class="fe_btn fe_btn_completion btn_completion" id="quiz_complete_%d_%d">%s</a>
                    $html .= sprintf('<div class="wpcw_fe_quiz_submit wpcw_fe_quiz_submit_data">
					
										%s
									    
										<div class="wpcw_fe_submit_loader wpcw_loader">
											<img src="%simg/ajax_loader.gif" />
										</div>
										
										<input type="submit" class="fe_btn fe_btn_completion btn_completion" name="submit" value="%s">						
									</div>', WPCW_content_progressBar(0, 'wpcw_fe_upload_progress'), WPCW_plugin_getPluginPath(), __('Submit Answers', 'wp_courseware'));
                }
                // end of check for paging.
            }
            // end of check of showing questions (e.g. timer mode)
        }
        // end of question check
        $html .= '</div>';
        // .wpcw_fe_quiz_box
        $html .= '</form>';
        $html .= '</div>';
        // .wpcw_fe_quiz_box_wrap
        return $html;
    }
Example #2
0
/**
 * Convert a time in minutes to a human label.
 * @param Integer $minutes The time in minutes.
 * @return String The time in hours, minutes and seconds.
 */
function WPCW_time_convertMinutesToHumanLabel($minutes)
{
    return WPCW_time_convertSecondsToHumanLabel($minutes * 60);
}