/** * Create user progress object. * * @param Integer $courseID The ID of the course that we're checking. * @param Integer $userID The ID of the user that we're checking. */ function __construct($courseID, $userID) { $this->courseID = $courseID; $this->userID = $userID; // Work out if access allowed $this->canAccessCourse = WPCW_courses_canUserAccessCourse($this->courseID, $this->userID); // Work out if want walled access to units $this->userCanOnlyAccessNext = false; $courseDetails = WPCW_courses_getCourseDetails($this->courseID); // Completion wall is set, so need to stop access to all units. if ($courseDetails && 'completion_wall' == $courseDetails->course_opt_completion_wall) { $this->userCanOnlyAccessNext = true; } // Get the next item user is allowed to access $this->nextUnitLoaded = false; $this->nextUnit = false; }
/** * Function called when a user is submitting quiz answers via * the frontend form. */ function WPCW_AJAX_units_handleQuizResponse() { // Security check if (!wp_verify_nonce(WPCW_arrays_getValue($_POST, 'progress_nonce'), 'wpcw-progress-nonce')) { die(__('Security check failed!', 'wp_courseware')); } // Quiz ID and Unit ID are combined in the single CSS ID for validation. // So validate both are correct and that user is allowed to access quiz. $quizAndUnitID = WPCW_arrays_getValue($_POST, 'id'); // e.g. quiz_complete_69_1 or quiz_complete_17_2 (first ID is unit, 2nd ID is quiz) if (!preg_match('/quiz_complete_(\\d+)_(\\d+)/', $quizAndUnitID, $matches)) { echo WPCW_units_getCompletionBox_error(); die; } // Use the extracted data for further validation $unitID = $matches[1]; $quizID = $matches[2]; $user_id = get_current_user_id(); // #### Get associated data for this unit. No course/module data, not a unit $parentData = WPCW_units_getAssociatedParentData($unitID); if (!$parentData) { // No error, as not a valid unit. die; } // #### User not allowed access to content, so certainly can't say they've done this unit. if (!WPCW_courses_canUserAccessCourse($parentData->course_id, $user_id)) { // No error, as not a valid unit. die; } // #### Check that the quiz is valid and belongs to this unit $quizDetails = WPCW_quizzes_getQuizDetails($quizID, true); if (!($quizDetails && $quizDetails->parent_unit_id == $unitID)) { die; } // Validate the quiz answers... which means we might have to // send back the form to be re-filled. $canContinue = WPCW_quizzes_handleQuizRendering_canUserContinueAfterQuiz($quizDetails, $_POST, $user_id); // Check that user is allowed to progress. if ($canContinue) { WPCW_units_saveUserProgress_Complete($user_id, $unitID, 'complete'); // Unit complete, check if course/module is complete too. do_action('wpcw_user_completed_unit', $user_id, $unitID, $parentData); // Only complete if allowed to continue. echo WPCW_units_getCompletionBox_complete($parentData, $unitID, $user_id); } die; }
/** * Shows a detailed summary of the user progress. */ function WPCW_showPage_UserProgess_load() { global $wpcwdb, $wpdb; $wpdb->show_errors(); $page = new PageBuilder(false); $page->showPageHeader(__('Detailed User Progress Report', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); // Check passed user ID is valid $userID = WPCW_arrays_getValue($_GET, 'user_id'); $userDetails = get_userdata($userID); if (!$userDetails) { $page->showMessage(__('Sorry, but that user could not be found.', 'wp_courseware'), true); $page->showPageFooter(); return false; } printf(__('<p>Here you can see how well <b>%s</b> (Username: <b>%s</b>) is doing with your training courses.</p>', 'wp_courseware'), $userDetails->data->display_name, $userDetails->data->user_login); // #### 1 - Show a list of all training courses, and then list the units associated with that course. $SQL = "SELECT * \n\t\t\tFROM {$wpcwdb->courses}\n\t\t\tORDER BY course_title ASC \n\t\t\t"; $courseCount = 0; $courses = $wpdb->get_results($SQL); if ($courses) { foreach ($courses as $course) { $up = new UserProgress($course->course_id, $userID); // Skip if user is not allowed to access the training course. if (!WPCW_courses_canUserAccessCourse($course->course_id, $userID)) { continue; } printf('<h3 class="wpcw_tbl_progress_course">%s</h3>', $course->course_title); printf('<table class="widefat wpcw_tbl wpcw_tbl_progress">'); printf('<thead>'); printf('<th>%s</th>', __('Unit', 'wp_courseware')); printf('<th class="wpcw_center">%s</th>', __('Completed', 'wp_courseware')); printf('<th class="wpcw_center wpcw_tbl_progress_quiz_name">%s</th>', __('Quiz Name', 'wp_courseware')); printf('<th class="wpcw_center">%s</th>', __('Quiz Status', 'wp_courseware')); printf('<th class="wpcw_center">%s</th>', __('Actions', 'wp_courseware')); printf('</thead><tbody>'); // #### 2 - Fetch all associated modules $modules = WPCW_courses_getModuleDetailsList($course->course_id); if ($modules) { foreach ($modules as $module) { // #### 3 - Render Modules as a heading. printf('<tr class="wpcw_tbl_progress_module">'); printf('<td colspan="3">%s %d - %s</td>', __('Module', 'wp_courseware'), $module->module_number, $module->module_title); // Blanks for Quiz Name and Actions. printf('<td> </td>'); printf('<td> </td>'); printf('</tr>'); // #### 4. - Render the units for this module $units = WPCW_units_getListOfUnits($module->module_id); if ($units) { foreach ($units as $unit) { $showDetailLink = false; printf('<tr class="wpcw_tbl_progress_unit">'); printf('<td class="wpcw_tbl_progress_unit_name">%s %d - %s</td>', __('Unit', 'wp_courseware'), $unit->unit_meta->unit_number, $unit->post_title); // Has the unit been completed yet? printf('<td class="wpcw_tbl_progress_completed">%s</td>', $up->isUnitCompleted($unit->ID) ? __('Completed', 'wp_courseware') : ''); // See if there's a quiz for this unit? $quizDetails = WPCW_quizzes_getAssociatedQuizForUnit($unit->ID, false, $userID); // Render the quiz details. if ($quizDetails) { // Title of quiz printf('<td class="wpcw_tbl_progress_quiz_name">%s</td>', $quizDetails->quiz_title); // No correct answers, so mark as complete. if ('survey' == $quizDetails->quiz_type) { $quizResults = WPCW_quizzes_getUserResultsForQuiz($userID, $unit->ID, $quizDetails->quiz_id); if ($quizResults) { printf('<td class="wpcw_tbl_progress_completed">%s</td>', __('Completed', 'wp_courseware')); // Showing a link to view details $showDetailLink = true; printf('<td><a href="%s&user_id=%d&quiz_id=%d&unit_id=%d" class="button-secondary">%s</a></td>', admin_url('users.php?page=WPCW_showPage_UserProgess_quizAnswers'), $userID, $quizDetails->quiz_id, $unit->ID, __('View Survey Details', 'wp_courseware')); } else { printf('<td class="wpcw_center">%s</td>', __('Pending', 'wp_courseware')); } } else { $quizResults = WPCW_quizzes_getUserResultsForQuiz($userID, $unit->ID, $quizDetails->quiz_id); // Show the admin how many questions were right. if ($quizResults) { // -1% means that the quiz is needing grading. if ($quizResults->quiz_grade < 0) { printf('<td class="wpcw_center">%s</td>', __('Awaiting Final Grading', 'wp_courseware')); } else { printf('<td class="wpcw_tbl_progress_completed">%d%%</td>', number_format($quizResults->quiz_grade, 1)); } // Showing a link to view details $showDetailLink = true; printf('<td><a href="%s&user_id=%d&quiz_id=%d&unit_id=%d" class="button-secondary">%s</a></td>', admin_url('users.php?page=WPCW_showPage_UserProgess_quizAnswers'), $userID, $quizDetails->quiz_id, $unit->ID, __('View Quiz Details', 'wp_courseware')); } else { printf('<td class="wpcw_center">%s</td>', __('Pending', 'wp_courseware')); } } // end of if survey } else { printf('<td class="wpcw_center">-</td>'); printf('<td class="wpcw_center">-</td>'); } // Quiz detail link if (!$showDetailLink) { printf('<td> </td>'); } printf('</tr>'); } } } } printf('</tbody></table>'); // Track number of courses user can actually access $courseCount++; } // Course is not allowed to access any courses. So show a meaningful message. if ($courseCount == 0) { $page->showMessage(sprintf(__('User <b>%s</b> is not currently allowed to access any training courses.', 'wp_courseware'), $userDetails->data->display_name), true); } } else { printf('<p>%s</p>', __('There are currently no courses to show. Why not create one?', 'wp_courseware')); } $page->showPageFooter(); }
/** * Page where the site owner can choose which courses a user is allowed to access. */ function WPCW_showPage_UserCourseAccess_load() { global $wpcwdb, $wpdb; $wpdb->show_errors(); $page = new PageBuilder(false); $page->showPageHeader(__('Update User Course Access Permissions', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); // Check passed user ID is valid $userID = WPCW_arrays_getValue($_GET, 'user_id'); $userDetails = get_userdata($userID); if (!$userDetails) { $page->showMessage(__('Sorry, but that user could not be found.', 'wp_courseware'), true); $page->showPageFooter(); return false; } printf(__('<p>Here you can change which courses the user <b>%s</b> (Username: <b>%s</b>) can access.</p>', 'wp_courseware'), $userDetails->data->display_name, $userDetails->data->user_login); // Check to see if anything has been submitted? if (isset($_POST['wpcw_course_user_access'])) { $subUserID = WPCW_arrays_getValue($_POST, 'user_id') + 0; $userSubDetails = get_userdata($subUserID); // Check that user ID is valid, and that it matches user we're editing. if (!$userSubDetails || $subUserID != $userID) { $page->showMessage(__('Sorry, but that user could not be found. The changes were not saved.', 'wp_courseware'), true); } else { // Get list of courses that user is allowed to access from the submitted values. $courseAccessIDs = array(); foreach ($_POST as $key => $value) { // Check for course ID selection if (preg_match('/^wpcw_course_(\\d+)$/', $key, $matches)) { $courseAccessIDs[] = $matches[1]; } } // Sync courses that the user is allowed to access WPCW_courses_syncUserAccess($subUserID, $courseAccessIDs, 'sync'); // Final success message $message = sprintf(__('The courses for user <em>%s</em> have now been updated.', 'wp_courseware'), $userDetails->data->display_name); $page->showMessage($message, false); } } $SQL = "SELECT * \n\t\t\tFROM {$wpcwdb->courses}\n\t\t\tORDER BY course_title ASC \n\t\t\t"; $courses = $wpdb->get_results($SQL); if ($courses) { $tbl = new TableBuilder(); $tbl->attributes = array('id' => 'wpcw_tbl_course_access_summary', 'class' => 'widefat wpcw_tbl'); $tblCol = new TableColumn(__('Allowed Access', 'wp_courseware'), 'allowed_access'); $tblCol->cellClass = "allowed_access"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Course Title', 'wp_courseware'), 'course_title'); $tblCol->cellClass = "course_title"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Description', 'wp_courseware'), 'course_desc'); $tblCol->cellClass = "course_desc"; $tbl->addColumn($tblCol); // Format row data and show it. $odd = false; foreach ($courses as $course) { $data = array(); // Basic details $data['course_desc'] = $course->course_desc; $editURL = admin_url('admin.php?page=WPCW_showPage_ModifyCourse&course_id=' . $course->course_id); $data['course_title'] = sprintf('<a href="%s">%s</a>', $editURL, $course->course_title); // Checkbox if enabled or not $userAccess = WPCW_courses_canUserAccessCourse($course->course_id, $userID); $checkedHTML = $userAccess ? 'checked="checked"' : ''; $data['allowed_access'] = sprintf('<input type="checkbox" name="wpcw_course_%d" %s/>', $course->course_id, $checkedHTML); // Odd/Even row colouring. $odd = !$odd; $tbl->addRow($data, $odd ? 'alternate' : ''); } // Create a form so user can update access. ?> <form action="<?php str_replace('%7E', '~', $_SERVER['REQUEST_URI']); ?> " method="post"> <?php // Finally show table echo $tbl->toString(); ?> <input type="hidden" name="user_id" value="<?php echo $userID; ?> "> <input type="submit" class="button-primary" name="wpcw_course_user_access" value="<?php _e('Save Changes', 'wp_courseware'); ?> " /> </form> <?php } else { printf('<p>%s</p>', __('There are currently no courses to show. Why not create one?', 'wp_courseware')); } $page->showPageFooter(); }