Beispiel #1
0
/**
 * Convert a percentage to a percentage bar
 * @param String $percent The number to show in the progress bar.
 * @param String $title The optional title of the course.
 * 
 * @return String The HTML to render the percentage bar.
 */
function WPCW_stats_convertPercentageToBar($percent, $title = false)
{
    if ($title) {
        $title = sprintf('<span class="wpcw_progress_bar_title">%s</span>', $title);
    }
    return WPCW_content_progressBar($percent, false, $title);
}
    /**
     * 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;
    }
Beispiel #3
0
/**
 * Creates widget that shows off the user's progress on their respective courses.
 * 
 *  e.g. [wpcourse_progress courses="2" user_progress="true" user_grade="true" /]
 */
function WPCW_shortcodes_showTrainingCourseProgress($atts, $content)
{
    extract(shortcode_atts(array('courses' => 'all', 'user_progress' => true, 'user_grade' => true), $atts));
    // Check flags to see what we're showing
    $showUserProgress = 'true' == strtolower($user_progress);
    $showUserGrade = 'true' == strtolower($user_grade);
    // Show a message to the user if they are not logged in.
    $user_id = get_current_user_id();
    if (!$user_id) {
        return sprintf('<div class="wpcw_fe_progress_box_wrap"><div class="wpcw_fe_progress_box wpcw_fe_progress_box_error">%s</div></div>', apply_filters('wpcw_front_shortcode_wpcourse_progress_notloggedin', __('You need to be logged in to see your course progress.', 'wp_courseware')));
    }
    // Get a list of all of the courses that the user is subscribed to.
    $courseList = WPCW_users_getUserCourseList($user_id);
    $selectedCourseList = array();
    // Filter the list of courses to remove the ones that the trainer doesn't
    // want the user to see. 'all' means show all courses with no filtering.
    // Only do this check if we have any courses to check, to save time.
    if (!empty($courseList) && 'all' != strtolower($courses)) {
        $selectedCourseList = explode(',', $courses);
        // This is the list of courses we'll actually use.
        $chosenListOfCourses = array();
        // We've got courses that have been specified, so we need to go through them now.
        if (!empty($selectedCourseList)) {
            foreach ($selectedCourseList as $potentialItem) {
                $potentialItem = trim($potentialItem);
                // Got a potential ID here.
                if (preg_match('/^([0-9]+)$/', $potentialItem)) {
                    // Check each course we still have to see if the ID matches.
                    // I know it's O(N), but it's simple at least.
                    foreach ($courseList as $idx => $aSingleCourse) {
                        // Got a match...
                        if ($potentialItem == $aSingleCourse->course_id) {
                            // Move the chosen course to the selected list. Doing
                            // so makes subsequent searches faster.
                            $chosenListOfCourses[] = $aSingleCourse;
                            unset($courseList[$idx]);
                            // Stop searching, we found it.
                            break;
                        }
                    }
                    // end foreach
                }
                // end ID check
            }
            // end foreach of potential IDs in list.
        }
        // Overwrite the list of courses to use.
        $courseList = $chosenListOfCourses;
    }
    // Handle when the list is empty
    if (empty($courseList)) {
        // Change message slightly based on how many courses are selected.
        $messageToShow = __('You are not currently enrolled on any courses.', 'wp_courseware');
        if (!empty($selectedCourseList)) {
            $messageToShow = __('You are not currently enrolled on any of these courses.', 'wp_courseware');
        }
        return sprintf('<div class="wpcw_fe_progress_box_wrap"><div class="wpcw_fe_progress_box wpcw_fe_progress_box_error">%s</div></div>', apply_filters('wpcw_front_shortcode_wpcourse_progress_no_courses', $messageToShow, count($courseList)));
    }
    // Used to determine how many columns we have in the table for showing the course details.
    $columnCount = 1;
    // Show the list of courses
    $html = '<table id="wpcw_fe_course_progress" class="wpcw_fe_table wpcw_fe_summary_course_progress">';
    // The title bar for the course.
    $html .= '<thead><tr>';
    // Course name
    $html .= sprintf('<th class="wpcw_fe_course_progress_course">%s</th>', __('Course', 'wp_courseware'));
    // Course progress
    if ($showUserProgress) {
        $columnCount++;
        $html .= sprintf('<th class="wpcw_fe_course_progress_pc">%s</th>', __('Your Progress', 'wp_courseware'));
    }
    // Overall grade so far
    if ($showUserGrade) {
        $columnCount++;
        $html .= sprintf('<th class="wpcw_fe_course_progress_grade">%s</th>', __('Your Overall Grade', 'wp_courseware'));
    }
    $html .= '</tr></thead><tbody>';
    // The main body of the course information.
    foreach ($courseList as $aSingleCourse) {
        $html .= '<tr class="wpcw_fe_course_progress_row">';
        // Course name
        $html .= sprintf('<td class="wpcw_fe_course_progress_course"><a href="#" data-toggle="wpcw_fe_course_progress_detail_%d">%s</a></td>', $aSingleCourse->course_id, $aSingleCourse->course_title);
        // Course progress
        if ($showUserProgress) {
            $html .= sprintf('<td class="wpcw_fe_course_progress_pc">%s</td>', WPCW_content_progressBar($aSingleCourse->course_progress));
        }
        // Show the Overall grade so far
        if ($showUserGrade) {
            $html .= sprintf('<td class="wpcw_fe_course_progress_grade">%s</td>', WPCW_courses_getCourseCumulativeGrade($aSingleCourse->course_id, $user_id));
        }
        $html .= '</tr>';
        // Show full course details. This might be a setting at some point.
        $html .= sprintf('<tr><td class="wpcw_fe_course_progress_detail" id="wpcw_fe_course_progress_detail_%d" colspan="%d">', $aSingleCourse->course_id, $columnCount);
        $html .= WPCW_courses_renderCourseList($aSingleCourse->course_id, array('hide_credit_link' => true));
        $html .= '</td></tr>';
    }
    $html .= '</tbody></table>';
    // end .wpcw_fe_summary_course_progress
    return $html;
}