예제 #1
0
 /**
  * Renders WP-Coursware unit detail over [op-courseware] shortcode
  * @return string
  */
 public static function renderCoursewareUnitDetails()
 {
     global $post;
     if (class_exists('WPCW_UnitFrontend')) {
         $fe = new WPCW_UnitFrontend($post);
         return $fe->render_detailsForUnit("");
     }
 }
예제 #2
0
/**
 * Handle showing the box that allows a user to mark a unit as completed.
 */
function WPCW_units_processUnitContent($content)
{
    // #### Ensure we're only showing a course unit, a single item
    if (!is_single() || 'course_unit' != get_post_type()) {
        return $content;
    }
    // Use object to handle the rendering of the unit on the frontend.
    include_once WPCW_plugin_getPluginDirPath() . 'classes/class_frontend_unit.inc.php';
    global $post;
    $fe = new WPCW_UnitFrontend($post);
    // #### Get associated data for this unit. No course/module data, then it's not a unit
    if (!$fe->check_unit_doesUnitHaveParentData()) {
        return $content;
    }
    // #### Ensure we're logged in
    if (!$fe->check_user_isUserLoggedIn()) {
        return $fe->message_user_notLoggedIn();
    }
    // #### User not allowed access to content, so certainly can't say they've done this unit.
    if (!$fe->check_user_canUserAccessCourse()) {
        return $fe->message_user_cannotAccessCourse();
    }
    // #### Is user allowed to access this unit yet?
    if (!$fe->check_user_canUserAccessUnit()) {
        return $fe->message_user_cannotAccessUnit();
    }
    // ### Do the remaining rendering...
    return $fe->render_detailsForUnit($content);
}
예제 #3
0
 /**
  * Checks the supplied answers to see which questions are correct.
  * 
  * @return Boolean Returns true if the trainee can continue (either passed in blocking, or survey/non-blocking), false otherwise.
  */
 function check_quizzes_gradeQuestionsForQuiz()
 {
     // Use the quiz answers that need grading, stored in the local variable.
     $resultsList = $this->unchecked_QuizAnswersToGrade;
     $resultDetails = array('correct' => array(), 'wrong' => array());
     // Flag to indicate if grading is needed before the user continues.
     $gradingNeeded = false;
     $gradingNeededBeforeContinue = false;
     // If true, then we notify the user of the grade.
     $quizGradeNotificationNeeded = false;
     // ### 3 - Do we need to check for correct answers?
     if ('survey' == $this->unitQuizDetails->quiz_type) {
         // Show answers only if this is a survey where we want trainees to see the results.
         // @since V2.90
         $this->unitQuizDetails->quiz_show_answers = 'hide_answers';
         if ('show_responses' == $this->unitQuizDetails->quiz_show_survey_responses) {
             $this->unitQuizDetails->quiz_show_answers = 'show_answers';
         }
         // No answers to check. Say thanks
         echo WPCW_UnitFrontend::message_createMessage_success(__('Thank you for your responses. This unit is now complete.', 'wp_courseware'));
     } else {
         $resultDetails = $this->check_quizzes_checkForCorrectAnswers($resultsList['answer_list']);
         // #### Step A - have open-ended questions that need marking.
         if (!empty($resultDetails['needs_marking'])) {
             $gradingNeeded = true;
             $courseDetails = WPCW_courses_getCourseDetails($this->unitQuizDetails->parent_course_id);
             // Non-blocking quiz - so allowed to continue, but will be graded later.
             if ('quiz_block' == $this->unitQuizDetails->quiz_type) {
                 // Grading is needed before they continue, but don't want them to re-take the quiz.
                 $gradingNeededBeforeContinue = true;
             }
         } else {
             // Copy over the wrong answers.
             $resultsList['wrong_answer_list'] = $resultDetails['wrong'];
             // Some statistics
             $correctCount = count($resultDetails['correct']);
             $totalQuestions = count($this->unitQuizDetails->questions);
             $correctPercentage = number_format($correctCount / $totalQuestions * 100, 1);
             // Non-blocking quiz.
             if ('quiz_noblock' == $this->unitQuizDetails->quiz_type) {
                 // Store user quiz results
                 // 2014-07-11 - Deprecated. Now being generated by the message summary for quizzes.
                 /*
                 					echo WPCW_UnitFrontend::message_createMessage_success(sprintf(__('You got <b>%d out of %d (%d%%)</b> questions correct! This unit is now complete.', 'wp_courseware'),
                 							$correctCount, $totalQuestions, $correctPercentage
                 						))*/
                 // Notify the user of their grade.
                 $quizGradeNotificationNeeded = true;
             } else {
                 // 2014-01-15 - Added ceil() calculation to ensure calculation is consistent when showing the quiz title
                 // above around the .wpcw_fe_quiz_title div.
                 $minPassQuestions = ceil($this->unitQuizDetails->quiz_pass_mark / 100 * $totalQuestions);
                 // They've passed. Report how many they got right.
                 if ($correctPercentage >= $this->unitQuizDetails->quiz_pass_mark) {
                     // 2014-07-11 - Deprecated. Now being generated by the message summary for quizzes.
                     /*echo WPCW_UnitFrontend::message_createMessage_success(sprintf(__('You got <b>%d out of %d (%d%%)</b> questions correct! This unit is now complete.', 'wp_courseware'),
                     			$correctCount, $totalQuestions, $correctPercentage
                     		));*/
                     // Notify the user of their grade.
                     $quizGradeNotificationNeeded = true;
                 } else {
                     // 2014-07-11 - Deprecated. Now being generated by the message summary for quizzes.
                     // Show error that they've failed
                     /*echo WPCW_UnitFrontend::message_createMessage_error(
                     			sprintf(__('Unfortunately, you only got <b>%d out of %d (%d%%)</b> questions correct. You need to correctly answer <b>at least %d questions (%d%%)</b>.', 'wp_courseware'),
                     			$correctCount, $totalQuestions, $correctPercentage,
                     			$minPassQuestions, $this->unitQuizDetails->quiz_pass_mark
                     		));*/
                     // Save the user progress anyway, so that we can record attempts.
                     $this->update_quizzes_saveUserProgress_completeQuiz($resultDetails, $resultsList['answer_list']);
                     // Have they run out of quiz attempts? If so, we need to notify the admin and mark the latest attempt
                     // as being the the last blocked one they can use.
                     if (!$this->check_quizzes_canUserRequestRetake()) {
                         // Update progress in database with next new step.
                         $this->update_quizzes_setNextStepData('quiz_fail_no_retakes', false);
                         // Notify the admin that this user is blocked and needs unblocking
                         do_action('wpcw_quiz_user_needs_unblocking', $this->currentUserID, $this->unitQuizDetails);
                     }
                     // 2014-07-11 - Deprecated. Now being generated by the message summary for quizzes.
                     // How many attempts have they now had?
                     /*
                     						$attemptCount = $this->fetch_quizzes_getQuizAttemptCount();
                     						echo WPCW_UnitFrontend::message_createMessage_error(
                     							($attemptCount == 1 
                     									? __('You have already had 1 previous attempt at this quiz.', 'wp_courseware')  
                     									: sprintf(__('You have already had %d previous attempts at this quiz.', 'wp_courseware'), $attemptCount)
                     						));*/
                     // 2014-07-11 - Deprecated. Now being generated by the message summary for quizzes.
                     // If quiz is a no-answers quiz, show the form without the errors, so that the user cannot keep guesssing to pass.
                     //echo $this->render_quizzes_old_handleQuizRendering($resultsList, ('no_answers' != $this->unitQuizDetails->quiz_show_answers));
                     // Errors, so the user cannot progress yet.
                     return false;
                 }
             }
             // end of blocking quiz check
         }
     }
     // end of survey check
     // ### 4 - Save the user progress
     $this->update_quizzes_saveUserProgress_completeQuiz($resultDetails, $resultsList['answer_list']);
     // ### 5 - Notify the user of their grade.
     if ($quizGradeNotificationNeeded) {
         do_action('wpcw_quiz_graded', $this->currentUserID, $this->unitQuizDetails, false, false);
     }
     // Questions need grading, notify the admin
     if ($gradingNeeded) {
         // Notify the admin that questions need answering.
         do_action('wpcw_quiz_needs_grading', $this->currentUserID, $this->unitQuizDetails);
     }
     // Questions need grading, so don't allow user to continue
     if ($gradingNeededBeforeContinue) {
         return false;
     }
     // If we get this far, the user may progress to next unit
     return true;
 }
예제 #4
0
/**
 * Given a frontend object with user progress data, replace the tags with quiz-related information
 * based on the tags that have been found in the email.
 * 
 * @param WPCW_UnitFrontend $feObj The frontend object with details.
 * @param Array $tagList The list of tags found in the template.
 * @param String $emailData The data to replace the strings with.
 * @param String $additionalData Any additional data triggered from the trainer.
 * 
 * @return The modified email data ready for sending.
 */
function WPCW_email_replaceTags_quizData($feObj, $tagList, $emailData, $additionalData = false)
{
    if (!$feObj || empty($tagList)) {
        return $emailData;
    }
    $quizDetails = $feObj->fetch_getUnitQuizDetails();
    $progressData = $feObj->fetch_getQuizProgressDetails();
    // Replace each tag for quiz-related data.
    foreach ($tagList as $tagToReplace) {
        switch ($tagToReplace) {
            case '{QUIZ_TITLE}':
                $emailData = str_replace('{QUIZ_TITLE}', $quizDetails->quiz_title, $emailData);
                break;
            case '{QUIZ_GRADE}':
                $emailData = str_replace('{QUIZ_GRADE}', $progressData->quiz_grade . '%', $emailData);
                break;
            case '{QUIZ_ATTEMPTS}':
                $emailData = str_replace('{QUIZ_ATTEMPTS}', $progressData->attempt_count, $emailData);
                break;
            case '{QUIZ_TIME}':
                $timeToShare = __('n/a', 'wp_courseware');
                if ($progressData->quiz_completion_time_seconds > 0) {
                    $timeToShare = WPCW_time_convertSecondsToHumanLabel($progressData->quiz_completion_time_seconds);
                }
                $emailData = str_replace('{QUIZ_TIME}', $timeToShare, $emailData);
                break;
            case '{QUIZ_RESULT_DETAIL}':
                $emailData = str_replace('{QUIZ_RESULT_DETAIL}', $additionalData, $emailData);
                break;
            case '{QUIZ_GRADES_BY_TAG}':
                // Use existing frontend code to get the list of messages relating to tags.
                $msgList = $feObj->fetch_quizzes_questionResultsByTag();
                $msgSummary = false;
                if (!empty($msgList)) {
                    foreach ($msgList as $tagDetails) {
                        // Got open questions
                        if ($tagDetails['question_open_count'] > 0) {
                            $msgSummary .= sprintf("%s: %s\n", $tagDetails['tag_details']->question_tag_name, sprintf(__('Your grade is %d%%', 'wp_courseware'), $tagDetails['score_total']));
                        } else {
                            $msgSummary .= sprintf("%s: %s\n", $tagDetails['tag_details']->question_tag_name, sprintf(__('%d out of %d correct (%d%%)', 'wp_courseware'), $tagDetails['score_correct_questions'], $tagDetails['question_count'], $tagDetails['score_total']));
                        }
                        // end of question type check
                    }
                }
                $emailData = str_replace('{QUIZ_GRADES_BY_TAG}', $msgSummary, $emailData);
                break;
            case '{CUSTOM_FEEDBACK}':
                // Use existing frontend code to get the list of custom feedback messages.
                $customFeedback = false;
                $msgList = $feObj->fetch_customFeedbackMessage_calculateMessages();
                if (!empty($msgList)) {
                    $customFeedback = apply_filters('wpcw_email_feedback_separator_top', "\n\n------\n\n");
                    foreach ($msgList as $singleMsg) {
                        // Separate each custom feedback message slightly
                        $customFeedback .= $singleMsg . apply_filters('wpcw_email_feedback_separator', "\n\n------\n\n");
                    }
                }
                $emailData = str_replace('{CUSTOM_FEEDBACK}', $customFeedback, $emailData);
                break;
        }
    }
    return $emailData;
}
/**
 * Function called when user starting a quiz and needs to kick off the timer.
 */
function WPCW_AJAX_units_handleQuizTimerBegin()
{
    // Security check
    if (!wp_verify_nonce(WPCW_arrays_getValue($_POST, 'progress_nonce'), 'wpcw-progress-nonce')) {
        die(__('Security check failed!', 'wp_courseware'));
    }
    // Get unit and quiz ID
    $unitID = intval(WPCW_arrays_getValue($_POST, 'unitid'));
    $quizID = intval(WPCW_arrays_getValue($_POST, 'quizid'));
    // Get the post object for this quiz item.
    $post = get_post($unitID);
    if (!$post) {
        echo WPCW_UnitFrontend::message_createMessage_error(__('Error - could not start the timer for the quiz.', 'wp_courseware') . ' ' . __('Could not find training unit.', 'wp_courseware'));
        die;
    }
    // Initalise the unit details
    $fe = new WPCW_UnitFrontend($post);
    // #### Get associated data for this unit. No course/module data, then it's not a unit
    if (!$fe->check_unit_doesUnitHaveParentData()) {
        echo WPCW_UnitFrontend::message_createMessage_error(__('Error - could not start the timer for the quiz.', 'wp_courseware') . ' ' . __('Could not find course details for unit.', 'wp_courseware'));
        die;
    }
    // #### User not allowed access to content
    if (!$fe->check_user_canUserAccessCourse()) {
        echo $fe->message_user_cannotAccessCourse();
        die;
    }
    // #### See if we're in a position to retake this quiz?
    if (!$fe->check_quizzes_canUserRequestRetake()) {
        echo WPCW_UnitFrontend::message_createMessage_error(__('Error - could not start the timer for the quiz.', 'wp_courseware') . ' ' . __('You are not permitted to retake this quiz.', 'wp_courseware'));
        die;
    }
    // Trigger the upgrade to progress so that we can start the quiz, and trigger the timer.
    $fe->update_quizzes_beginQuiz();
    // Only complete if allowed to continue.
    echo $fe->render_detailsForUnit(false, true);
    die;
}
예제 #6
0
// Check that plugin is active (so that this cannot be accessed if plugin isn't).
require dirname(__FILE__) . '/../../../wp-config.php';
// Can't find active WP Courseware init function, so cannot be active.
if (!function_exists('WPCW_plugin_init')) {
    WPCW_export_results_notFound();
}
// Get unit and quiz ID
$unitID = intval(WPCW_arrays_getValue($_GET, 'unitid'));
$quizID = intval(WPCW_arrays_getValue($_GET, 'quizid'));
// Get the post object for this quiz item.
$post = get_post($unitID);
if (!$post) {
    WPCW_export_results_notFound(__('Could not find training unit.', 'wp_courseware'));
}
// Initalise the unit details
$fe = new WPCW_UnitFrontend($post);
// #### Get associated data for this unit. No course/module data, then it's not a unit
if (!$fe->check_unit_doesUnitHaveParentData()) {
    WPCW_export_results_notFound(__('Could not find course details for unit.', 'wp_courseware'));
}
// #### User not allowed access to content
if (!$fe->check_user_canUserAccessCourse()) {
    WPCW_export_results_notFound($fe->fetch_message_user_cannotAccessCourse());
}
include_once 'pdf/pdf_quizresults.inc.php';
$qrpdf = new WPCW_QuizResults();
$parentData = $fe->fetch_getUnitParentData();
$quizDetails = $fe->fetch_getUnitQuizDetails();
// Set values for use in the results
$qrpdf->setTraineeName(WPCW_users_getUsersName($current_user));
$qrpdf->setCourseName($parentData->course_title);