/** * See if there's a course to export based on $_POST variables. If so, trigger the export and XML download. * @param Boolean $triggerFileDownload If true, trigger a file download rather than just XML output as a page. */ public static function tryExportCourse($triggerFileDownload = true) { // See if course is being exported if (isset($_POST["update"]) && $_POST["update"] == 'wpcw_export' && current_user_can('manage_options')) { // Now check course is valid. If not, then don't do anything, and let // normal form handle the errors. $courseID = WPCW_arrays_getValue($_POST, 'export_course_id'); $courseDetails = WPCW_courses_getCourseDetails($courseID); if ($courseDetails) { $moduleList = false; // Work out what details to fetch and then export $whatToExport = WPCW_arrays_getValue($_POST, 'what_to_export'); switch ($whatToExport) { // Just the course title, description and settings (no units or modules) case 'just_course': break; // Just the course settings and module settings (no units) // Just the course settings and module settings (no units) case 'course_modules': $moduleList = WPCW_courses_getModuleDetailsList($courseDetails->course_id); break; // Basically case 'whole_course' - The whole course, modules and units // Basically case 'whole_course' - The whole course, modules and units default: $moduleList = WPCW_courses_getModuleDetailsList($courseDetails->course_id); if ($moduleList) { // Grab units for each module, in the right order, and associate with each module object. foreach ($moduleList as $module) { // This might return false, but that's OK. We'll check for it later. $module->units = WPCW_units_getListOfUnits($module->module_id); } } break; } // If true, trigger a file download of the XML file. if ($triggerFileDownload) { $exportFile = "wp-courseware-export-" . date("Y-m-d") . ".xml"; header('Content-Description: File Transfer'); header("Content-Disposition: attachment; filename={$exportFile}"); } header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true); // When debugging, comment out the line above, and use the following line so that you can see // any error messages. // header('Content-Type: text/plain'); $export = new WPCW_Export(); echo $export->exportCourseDetails($courseDetails, $moduleList); die; } } // If get here, then normal WPCW processing takes place. }
/** * Function that show a summary of the training courses. */ function WPCW_showPage_Dashboard_load() { $page = new PageBuilder(false); $page->showPageHeader(__('My Training Courses', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); // Handle any deletion WPCW_handler_processDeletion($page); // Handle the sorting and filtering $orderBy = WPCW_arrays_getValue($_GET, 'orderby'); $ordering = WPCW_arrays_getValue($_GET, 'order'); // Validate ordering switch ($orderBy) { case 'course_title': case 'course_id': break; default: $orderBy = 'course_title'; break; } // Create opposite ordering for reversing it. $ordering_opposite = false; switch ($ordering) { case 'desc': $ordering_opposite = 'asc'; break; case 'asc': $ordering_opposite = 'desc'; break; default: $ordering = 'asc'; $ordering_opposite = 'desc'; break; } // This data has been validated, so ok to use without prepare global $wpcwdb, $wpdb; $SQL = "\n\t\t\tSELECT * \n\t\t\tFROM {$wpcwdb->courses}\n\t\t\tORDER BY {$orderBy} {$ordering}"; $courses = $wpdb->get_results($SQL); if ($courses) { $tbl = new TableBuilder(); $tbl->attributes = array('id' => 'wpcw_tbl_course_summary', 'class' => 'widefat wpcw_tbl'); // ID - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=course_id"><span>%s</span><span class="sorting-indicator"></span></a>', admin_url('admin.php?page=WPCW_wp_courseware'), 'course_id' == $orderBy ? $ordering_opposite : 'asc', __('ID', 'wp_courseware')); // ID - render $tblCol = new TableColumn($sortableLink, 'course_id'); $tblCol->cellClass = "course_id"; $tblCol->headerClass = 'course_id' == $orderBy ? 'sorted ' . $ordering : 'sortable'; $tbl->addColumn($tblCol); // Title - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=course_title"><span>%s</span><span class="sorting-indicator"></span></a>', admin_url('admin.php?page=WPCW_wp_courseware'), 'course_title' == $orderBy ? $ordering_opposite : 'asc', __('Course Title', 'wp_courseware')); // Title - render $tblCol = new TableColumn($sortableLink, 'course_title'); $tblCol->headerClass = 'course_title' == $orderBy ? 'sorted ' . $ordering : 'sortable'; $tblCol->cellClass = "course_title"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Description', 'wp_courseware'), 'course_desc'); $tblCol->cellClass = "course_desc"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Settings', 'wp_courseware'), 'course_settings'); $tblCol->cellClass = "course_settings"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Total Units', 'wp_courseware'), 'total_units'); $tblCol->cellClass = "total_units"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Modules', 'wp_courseware'), 'course_modules'); $tblCol->cellClass = "course_modules"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Actions', 'wp_courseware'), 'actions'); $tblCol->cellClass = "actions"; $tbl->addColumn($tblCol); // Links $editURL = admin_url('admin.php?page=WPCW_showPage_ModifyCourse'); $url_addModule = admin_url('admin.php?page=WPCW_showPage_ModifyModule'); $url_ordering = admin_url('admin.php?page=WPCW_showPage_CourseOrdering'); $url_gradeBook = admin_url('admin.php?page=WPCW_showPage_GradeBook'); // Format row data and show it. $odd = false; foreach ($courses as $course) { $data = array(); // Basic Details $data['course_id'] = $course->course_id; $data['course_desc'] = $course->course_desc; // Editing Link $data['course_title'] = sprintf('<a href="%s&course_id=%d">%s</a>', $editURL, $course->course_id, $course->course_title); // Actions $data['actions'] = '<ul>'; $data['actions'] .= sprintf('<li><a href="%s&course_id=%d" class="button-primary">%s</a></li>', $url_addModule, $course->course_id, __('Add Module', 'wp_courseware')); $data['actions'] .= sprintf('<li><a href="%s&course_id=%d" class="button-secondary">%s</a></li>', $editURL, $course->course_id, __('Edit Course Settings', 'wp_courseware')); $data['actions'] .= sprintf('<li><a href="%s&course_id=%d" class="button-secondary">%s</a></li>', $url_ordering, $course->course_id, __('Modules, Units & Quiz Ordering', 'wp_courseware')); $data['actions'] .= sprintf('<li><a href="%s&course_id=%d" class="button-secondary">%s</a></li>', $url_gradeBook, $course->course_id, __('Access Grade Book', 'wp_courseware')); $data['actions'] .= '</ul>'; // Settings Summary - to allow user to see a quick overview of the current settings. $data['course_settings'] = '<ul class="wpcw_tickitems">'; // Access control - filtered if membership plugin $data['course_settings'] .= apply_filters('wpcw_extensions_access_control_override', sprintf('<li class="wpcw_%s">%s</li>', 'default_show' == $course->course_opt_user_access ? 'enabled' : 'disabled', __('Give new users access by default', 'wp_courseware'))); // Completion wall $data['course_settings'] .= sprintf('<li class="wpcw_%s">%s</li>', 'completion_wall' == $course->course_opt_completion_wall ? 'enabled' : 'disabled', __('Require unit completion before showing next', 'wp_courseware')); // Certificate handling $data['course_settings'] .= sprintf('<li class="wpcw_%s">%s</li>', 'use_certs' == $course->course_opt_use_certificate ? 'enabled' : 'disabled', __('Generate certificates on course completion', 'wp_courseware')); $data['course_settings'] .= '</ul>'; // Module list $data['course_modules'] = false; $moduleList = WPCW_courses_getModuleDetailsList($course->course_id); $moduleIDList = array(); if ($moduleList) { foreach ($moduleList as $item_id => $moduleObj) { $modName = sprintf('%s %d - %s', __('Module', 'wp_courseware'), $moduleObj->module_number, $moduleObj->module_title); // Create each module item with an edit link. $modEditURL = admin_url('admin.php?page=WPCW_showPage_ModifyModule&module_id=' . $item_id); $data['course_modules'] .= sprintf('<li><a href="%s" title="%s \'%s\'">%s</a></li>', $modEditURL, __('Edit Module', 'wp_courseware'), $modName, $modName); // Just want module IDs $moduleIDList[] = $item_id; } } else { $data['course_modules'] = __('No modules yet.', 'wp_courseware'); } // Unit Count if (count($moduleIDList) > 0) { $data['total_units'] = $wpdb->get_var("\n\t\t\t\t\tSELECT COUNT(*) \n\t\t\t\t\tFROM {$wpcwdb->units_meta} \n\t\t\t\t\tWHERE parent_module_id IN (" . implode(",", $moduleIDList) . ")"); } else { $data['total_units'] = '0'; } // Odd/Even row colouring. $odd = !$odd; $rowClass = $odd ? 'alternate' : ''; // Get a list of all quizzes for the specified parent course. $listOfQuizzes = $wpdb->get_col($wpdb->prepare("\n\t\t\t\tSELECT quiz_id\n\t\t\t\tFROM {$wpcwdb->quiz}\n\t\t\t\tWHERE parent_course_id = %d\n\t\t\t", $course->course_id)); $countOfQuizzesNeedingGrading = false; $countOfQuizzesNeedingManualHelp = false; // Determine if there are any quizzes that need marking. If so, how many? if (!empty($listOfQuizzes)) { $quizIDList = '(' . implode(',', $listOfQuizzes) . ')'; $countOfQuizzesNeedingGrading = $wpdb->get_var("\n\t\t\t\t\tSELECT COUNT(*)\n\t\t\t\t\tFROM {$wpcwdb->user_progress_quiz}\n\t\t\t\t\tWHERE quiz_id IN {$quizIDList}\n\t\t\t\t\t AND quiz_needs_marking > 0\n\t\t\t\t\t AND quiz_is_latest = 'latest'\n\t\t\t\t"); $countOfQuizzesNeedingManualHelp = $wpdb->get_var("\n\t\t\t\t\tSELECT COUNT(*)\n\t\t\t\t\tFROM {$wpcwdb->user_progress_quiz}\n\t\t\t\t\tWHERE quiz_id IN {$quizIDList}\n\t\t\t\t\t AND quiz_next_step_type = 'quiz_fail_no_retakes'\n\t\t\t\t\t AND quiz_is_latest = 'latest'\n\t\t\t\t"); } // Have we got any custom data for this row? $tblCustomRowStr = false; // Show the status message about quizzes needing marking. if ($countOfQuizzesNeedingGrading) { // Create message that quizzes need marking. $tblCustomRowStrTmp = __('This course has ', 'wp_courseware') . _n('1 quiz that requires', '%d quizzes that require', $countOfQuizzesNeedingGrading, 'wp_courseware') . __(' manual grading.', 'wp_courseware'); $tblCustomRowStr .= '<span>' . sprintf($tblCustomRowStrTmp, $countOfQuizzesNeedingGrading) . '</span>'; } // Show the status message about quizzes needing manual intervention. if ($countOfQuizzesNeedingManualHelp) { // Create message that quizzes need marking. $tblCustomRowStrTmp = __('This course has ', 'wp_courseware') . _n('1 user that is', '%d users that are', $countOfQuizzesNeedingManualHelp, 'wp_courseware') . __(' blocked due to too many failed attempts.', 'wp_courseware'); $tblCustomRowStr .= '<span>' . sprintf($tblCustomRowStrTmp, $countOfQuizzesNeedingManualHelp) . '</span>'; } // Add a row for the status data, hiding the border above it. if ($tblCustomRowStr) { // Create a row that also hides the border below it. $tbl->addRow($data, 'wpcw_tbl_row_status_pre ' . $rowClass); $tblRow = new RowDataSimple('wpcw_tbl_row_status ' . $rowClass, $tblCustomRowStr, 7); $tbl->addRowObj($tblRow); } else { $tbl->addRow($data, $rowClass); } } // Finally show table echo $tbl->toString(); } else { printf('<p>%s</p>', __('There are currently no courses to show. Why not create one?', 'wp_courseware')); } $page->showPageFooter(); }
/** * See if there's a course to export based on $_POST variables. If so, trigger the export and XML download. * @param Boolean $triggerFileDownload If true, trigger a file download rather than just XML output as a page. */ public static function tryExportCourse($triggerFileDownload = true) { // See if course is being exported if (isset($_POST["update"]) && $_POST["update"] == 'wpcw_export' && current_user_can('manage_options')) { // Now check course is valid. If not, then don't do anything, and let // normal form handle the errors. $courseID = WPCW_arrays_getValue($_POST, 'export_course_id'); $courseDetails = WPCW_courses_getCourseDetails($courseID); if ($courseDetails) { $moduleList = false; $questionList = false; // Work out what details to fetch and then export $whatToExport = WPCW_arrays_getValue($_POST, 'what_to_export'); switch ($whatToExport) { // Course Settings: Yes // Module Settings: No // Units: No // Quizzes: No case 'just_course': break; // Course Settings: Yes // Module Settings: Yes // Units: No // Quizzes: No // Course Settings: Yes // Module Settings: Yes // Units: No // Quizzes: No case 'course_modules': $moduleList = WPCW_courses_getModuleDetailsList($courseDetails->course_id); break; // Course Settings: Yes // Module Settings: Yes // Units: Yes // Quizzes: No // Course Settings: Yes // Module Settings: Yes // Units: Yes // Quizzes: No case 'course_modules_and_units': $moduleList = WPCW_courses_getModuleDetailsList($courseDetails->course_id); if ($moduleList) { // Grab units for each module, in the right order, and associate with each module object. foreach ($moduleList as $module) { // This might return false, but that's OK. We'll check for it later. $module->units = WPCW_units_getListOfUnits($module->module_id); } } break; // Basically the whole course // Course Settings: Yes // Module Settings: Yes // Units: Yes // Quizzes: Yes // Basically the whole course // Course Settings: Yes // Module Settings: Yes // Units: Yes // Quizzes: Yes default: $questionList = WPCW_questions_getAllQuestionsforCourse($courseDetails->course_id); $moduleList = WPCW_courses_getModuleDetailsList($courseDetails->course_id); if ($moduleList) { // Grab units for each module, in the right order, and associate with each module object. foreach ($moduleList as $module) { // This might return false, but that's OK. We'll check for it later. $module->units = WPCW_units_getListOfUnits($module->module_id); // See if we have any units, and then check each for the associated quiz data. // Update the unit objects with details of the quizzes WPCW_Export::WPCW_quizzes_fetchQuizzesForUnits($module->units); } } break; } // TODO ZZZ - DEBUG Tool - To enable debugging, comment this in so that the download is not triggered. $triggerFileDownload = true; // If true, trigger a file download of the XML file. if ($triggerFileDownload) { $exportFile = "wp-courseware-export-" . sanitize_title($courseDetails->course_title) . '-' . date("Y-m-d") . ".xml"; header('Content-Description: File Transfer'); header("Content-Disposition: attachment; filename={$exportFile}"); header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true); } else { // When debugging, comment out the line above, and use the following line so that you can see // any error messages. header('Content-Type: text/plain'); } $export = new WPCW_Export(); echo $export->exportCourseDetails($courseDetails, $moduleList, $questionList); die; } } // If get here, then normal WPCW processing takes place. }
/** * 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(); }
/** * Function that creates a list of units. * * @param Integer $courseID The ID of the course to show. * @param Array $options The list of options to show. */ function WPCW_courses_renderCourseList($courseID, $options) { extract(shortcode_atts(array('module' => 0, 'module_desc' => false, 'show_title' => false, 'show_desc' => false, 'widget_mode' => false, 'show_toggle_col' => false, 'show_modules_previous' => 'all', 'show_modules_next' => 'all', 'toggle_modules' => 'expand_all'), $options)); // Check settings to to see if they are true $module_desc = $module_desc == 'true'; $show_title = $show_title == 'true'; $show_desc = $show_desc == 'true'; $courseDetails = false; $parentData = false; global $post; // Show course based on current location for user. Use the currently shown post // to work out which course to show using the associated parent data. if ('current' == $courseID) { $parentData = WPCW_units_getAssociatedParentData($post->ID); if ($parentData) { $courseDetails = WPCW_courses_getCourseDetails($parentData->parent_course_id); $courseID = $parentData->parent_course_id; } else { return false; } } else { // Check course ID is valid $courseDetails = WPCW_courses_getCourseDetails($courseID); if (!$courseDetails) { return __('Unrecognised course ID.', 'wp_courseware'); } // Course ID is fine, get associated parent data for // hiding aspects of the widget $parentData = WPCW_units_getAssociatedParentData($post->ID); } $moduleList = false; // Do we just want a single module? if ($module > 0) { // Get module by module number within course (not the module ID) $moduleDetailsSingle = WPCW_modules_getModuleDetails_byModuleNumber($courseDetails->course_id, $module); if (!$moduleDetailsSingle) { return __('Could not find module.', 'wp_courseware'); } // Create module list of 1 using single module $moduleList[$moduleDetailsSingle->module_id] = $moduleDetailsSingle; } else { // Check there are modules $moduleList = WPCW_courses_getModuleDetailsList($courseID); if (!$moduleList) { return __('There are no modules in this training course.', 'wp_courseware'); } } $html = false; // #### Show course title/description if ($show_title) { $html .= sprintf('<div class="wpcw_fe_course_title">%s</div>', $courseDetails->course_title); } if ($show_desc) { $html .= sprintf('<div class="wpcw_fe_course_desc">%s</div>', $courseDetails->course_desc); } $html .= '<table id="wpcw_fe_course" cellspacing="0" cellborder="0">'; $showUnitLinks = false; // If true, show links to the units $colCount = 2; // Number of columns in the table // UP Object to determine what to show to the user. $userProgress = false; // Check user is logged in, and if they can access this course $user_id = get_current_user_id(); if ($user_id != 0) { $userProgress = new UserProgress($courseID, $user_id); // Show links for user if they are allowed to access this course. if ($userProgress->canUserAccessCourse()) { // User is logged in and can do course, so show the stuff they can do. $showUnitLinks = true; // Got an extra column to show progress $colCount = 3; } } // If we're showing a widget, and we have the parent data based on the // currently viewed unit, then change what's in the widget in terms // of previous/next units. $hideList = array(); if ($widget_mode && $module == 0 && $parentData) { // Build a list of the modules before and after the current // module, so that we can more easily control what's visible, // and what's not. $modulesBefore = array(); $modulesAfter = array(); $currentList =& $modulesBefore; foreach ($moduleList as $moduleID => $moduleObj) { // Switch lists, we've found the current module if ($moduleID == $parentData->parent_module_id) { $currentList =& $modulesAfter; } else { $currentList[] = $moduleID; } } // Handle showing previous modules switch ($show_modules_previous) { // All all items in the before list to be hidden case 'none': $hideList = array_merge($hideList, $modulesBefore); break; case 'all': break; // Keep a specific number of modules to show. // Keep a specific number of modules to show. default: $show_modules_previous += 0; $modulesToPickFrom = count($modulesBefore); // Remove the modules at the start of the list, leaving the right number of // $show_modules_previous modules in the list. if ($show_modules_previous > 0 && $modulesToPickFrom > $show_modules_previous) { $hideList = array_merge($hideList, array_slice($modulesBefore, 0, $modulesToPickFrom - $show_modules_previous)); } break; } // end switch // Handle showing the next modules. switch ($show_modules_next) { // All all items in the after list to be hidden case 'none': $hideList = array_merge($hideList, $modulesAfter); break; case 'all': break; // Keep a specific number of modules to show. // Keep a specific number of modules to show. default: $show_modules_next += 0; $modulesToPickFrom = count($modulesAfter); // Remove the modules at the start of the list, leaving the right number of // $show_modules_previous modules in the list. if ($show_modules_next > 0 && $modulesToPickFrom > $show_modules_next) { $hideList = array_merge($hideList, array_slice($modulesAfter, $show_modules_next)); } break; } // end switch } // Columns for marking item as being pending or complete. $progress_Complete = '<td class="wpcw_fe_unit_progress wpcw_fe_unit_progress_complete"><span> </span></td>'; $progress_Pending = '<td class="wpcw_fe_unit_progress wpcw_fe_unit_progress_incomplete"><span> </span></td>'; $progress_Blank = '<td class="wpcw_fe_unit_progress"><span> </span></td>'; // Show modules foreach ($moduleList as $moduleID => $moduleObj) { // See if we're skipping this module if (in_array($moduleID, $hideList)) { continue; } // If $collapseTitleArea is set to true, then the module will be collapsed. So just check what to hide // based on the contents of $toggle_modules $collapseTitleArea = false; if ($widget_mode && $parentData) { switch ($toggle_modules) { case 'contract_all': $collapseTitleArea = true; break; // See if the currently visible unit module is the one being rendered. // See if the currently visible unit module is the one being rendered. case 'contract_all_but_current': $collapseTitleArea = $moduleID != $parentData->parent_module_id; break; // Default is not to collapse. } } // We're showing the toggle section, so add it. if ($show_toggle_col) { $moduleTitleArea = false; $moduleTitleArea = sprintf('<td>%s</td><td class="wpcw_fe_toggle">%s</td>', $moduleObj->module_title, $collapseTitleArea ? '+' : '-'); } else { $moduleTitleArea = sprintf('<td colspan="%d">%s</td>', $colCount - 1, $moduleObj->module_title); } // Render final title bit $html .= sprintf('<tr class="wpcw_fe_module %s" id="wpcw_fe_module_group_%d"> <td>%s %d</td> ' . $moduleTitleArea . ' </tr>', $collapseTitleArea ? 'wpcw_fe_module_toggle_hide' : '', $moduleObj->module_number, __('Module', 'wp_courseware'), $moduleObj->module_number, $moduleTitleArea); // ### Showing the module descriptions? if ($module_desc) { $html .= sprintf('<tr class="wpcw_fe_module_des"><td colspan="%d">%s</td></tr>', $colCount, $moduleObj->module_desc); } // Add the class for the row that matches the parent module ID. $moduleRowClass = ' wpcw_fe_module_group_' . $moduleObj->module_number; // ### No Units Line $units = WPCW_units_getListOfUnits($moduleID); if (!$units) { $extraColSpan = 0; if ($show_toggle_col) { $extraColSpan = 1; } $html .= sprintf('<tr class="wpcw_fe_unit wpcw_fe_unit_none %s"> <td colspan="%d">%s</td> </tr>', $moduleRowClass, $colCount + $extraColSpan, __('There are no units in this module.', 'wp_courseware')); } else { // Render each unit foreach ($units as $unit) { $progressRow = false; $progressCol = false; // Show links for units if ($showUnitLinks) { // Yes we are showing progress data... see what state we're at. if ($userProgress) { if ($userProgress->isUnitCompleted($unit->ID)) { $progressCol = $progress_Complete; $progressRow = 'wpcw_fe_unit_complete'; } else { $progressCol = $progress_Pending; $progressRow = 'wpcw_fe_unit_pending'; } //$progressCol = ($userProgress->isUnitCompleted($unit->ID) ? $progress_Complete : $progress_Pending); } // See if the user is allowed to access this unit or not. if ($userProgress->canUserAccessUnit($unit->ID)) { // Main unit title, link and unit number $html .= sprintf(' <tr class="wpcw_fe_unit ' . $progressRow . $moduleRowClass . '"> <td>%s %d</td> <td class="wpcw_fe_unit"><a href="%s">%s</a></td> ' . $progressCol . ' </tr>', __('Unit', 'wp_courseware'), $unit->unit_meta->unit_number, get_permalink($unit->ID), $unit->post_title); } else { // If we're not allowed to access the unit, then it's always marked as pending. $html .= sprintf(' <tr class="wpcw_fe_unit ' . $progressRow . $moduleRowClass . '"> <td>%s %d</td> <td class="wpcw_fe_unit">%s</td> ' . $progress_Pending . ' </tr>', __('Unit', 'wp_courseware'), $unit->unit_meta->unit_number, $unit->post_title); } } else { $colspan = 1; if ($show_toggle_col) { $colspan = 2; } $html .= sprintf(' <tr class="wpcw_fe_unit ' . $progressRow . $moduleRowClass . '"> <td>%s %d</td> <td colspan="%d" class="wpcw_fe_unit">%s</td> </tr>', __('Unit', 'wp_courseware'), $unit->unit_meta->unit_number, $colspan, $unit->post_title); } } } // end show units } $html .= '</table>'; // Add powered by link $settings = TidySettings_getSettings(WPCW_DATABASE_SETTINGS_KEY); $html .= WPCW_generatedPoweredByLink($settings); return $html; }
/** * Page where the modules of a course can be ordered. */ function WPCW_showPage_CourseOrdering_load() { $page = new PageBuilder(false); $page->showPageHeader(__('Order Course Modules & Units', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); $courseDetails = false; $courseID = false; // Trying to edit a course if (isset($_GET['course_id'])) { $courseID = $_GET['course_id'] + 0; $courseDetails = WPCW_courses_getCourseDetails($courseID); } // Abort if course not found. if (!$courseDetails) { $page->showMessage(__('Sorry, but that course could not be found.', 'wp_courseware'), true); $page->showPageFooter(); return; } // ###ÊGenerate URLs for editing $modifyURL_quiz = admin_url('admin.php?page=WPCW_showPage_ModifyQuiz'); $modifyURL_module = admin_url('admin.php?page=WPCW_showPage_ModifyModule'); $modifyURL_unit = admin_url('post.php?action=edit'); // Title of course being editied printf('<div id="wpcw_page_course_title"><span>%s</span> %s</div>', __('Editing Course:', 'wp_courseware'), $courseDetails->course_title); // Overall wrapper printf('<div id="wpcw_dragable_wrapper">'); printf('<div id="wpcw_unassigned_wrapper" class="wpcw_floating_menu">'); // ### Show a list of units that are not currently assigned to a module printf('<div id="wpcw_unassigned_units" class="wpcw_unassigned">'); printf('<div class="wpcw_unassigned_title">%s</div>', __('Unassigned Units', 'wp_courseware')); printf('<ol class="wpcw_dragable_units_connected">'); // Render each unit so that it can be dragged to a module. Still render <ol> list // even if there are no units to show so that we can drag units into unassociated list. $units = WPCW_units_getListOfUnits(0); if ($units) { foreach ($units as $unassUnit) { // Has unit got any existing quizzes? $existingQuiz = false; $quizObj = WPCW_quizzes_getAssociatedQuizForUnit($unassUnit->ID, false, false); if ($quizObj) { $existingQuiz = sprintf('<li id="wpcw_quiz_%d" class="wpcw_dragable_quiz_item"> <div><a href="%s&quiz_id=%d" target="_blank" title="%s">%s (ID: %d)</a></div> <div class="wpcw_quiz_des">%s</div> </li>', $quizObj->quiz_id, $modifyURL_quiz, $quizObj->quiz_id, __('Edit this quiz...', 'wp_courseware'), $quizObj->quiz_title, $quizObj->quiz_id, $quizObj->quiz_desc); } printf('<li id="wpcw_unit_%d" class="wpcw_dragable_unit_item"> <div><a href="%s&post=%d" target="_blank" title="%s">%s (ID: %d)</a></div> <div class="wpcw_dragable_quiz_holder"><ol class="wpcw_dragable_quizzes_connected wpcw_one_only">%s</ol></div> </li>', $unassUnit->ID, $modifyURL_unit, $unassUnit->ID, __('Edit this unit...', 'wp_courseware'), $unassUnit->post_title, $unassUnit->ID, $existingQuiz); } } printf('</ol>'); printf('</div>'); // ### Show a list of quizzes that are not currently assigned to units printf('<div id="wpcw_unassigned_quizzes" class="wpcw_unassigned">'); printf('<div class="wpcw_unassigned_title">%s</div>', __('Unassigned Quizzes', 'wp_courseware')); printf('<ol class="wpcw_dragable_quizzes_connected">'); // Render each unit so that it can be dragged to a module. Still render <ol> list // even if there are no units to show so that we can drag units into unassociated list. $quizzes = WPCW_quizzes_getListOfQuizzes(0); if ($quizzes) { foreach ($quizzes as $quizObj) { printf('<li id="wpcw_quiz_%d" class="wpcw_dragable_quiz_item"> <div><a href="%s&quiz_id=%d" target="_blank" title="%s">%s (ID: %d)</a></div> <div class="wpcw_quiz_des">%s</div> </li>', $quizObj->quiz_id, $modifyURL_quiz, $quizObj->quiz_id, __('Edit this quiz...', 'wp_courseware'), $quizObj->quiz_title, $quizObj->quiz_id, $quizObj->quiz_desc); } } printf('</ol>'); printf('</div>'); printf('</div>'); // end of printf('<div class="wpcw_unassigned_wrapper">'); // ### Show list of modules and current units $moduleList = WPCW_courses_getModuleDetailsList($courseID); if ($moduleList) { printf('<ol class="wpcw_dragable_modules">'); foreach ($moduleList as $item_id => $moduleObj) { // Module printf('<li id="wpcw_mod_%d" class="wpcw_dragable_module_item"> <div> <a href="%s&module_id=%d" target="_blank" title="%s"><b>%s %d - %s (ID: %d)</b></a> </div>', $item_id, $modifyURL_module, $item_id, __('Edit this module...', 'wp_courseware'), __('Module', 'wp_courseware'), $moduleObj->module_number, $moduleObj->module_title, $item_id); // Test Associated Units printf('<ol class="wpcw_dragable_units_connected">'); $units = WPCW_units_getListOfUnits($item_id); if ($units) { foreach ($units as $unassUnit) { $existingQuiz = false; // Has unit got any existing quizzes? $quizObj = WPCW_quizzes_getAssociatedQuizForUnit($unassUnit->ID, false, false); $existingQuiz = false; if ($quizObj) { $existingQuiz = sprintf('<li id="wpcw_quiz_%d" class="wpcw_dragable_quiz_item"> <div><a href="%s&quiz_id=%d" target="_blank" title="%s">%s (ID: %d)</a></div> <div class="wpcw_quiz_des">%s</div> </li>', $quizObj->quiz_id, $modifyURL_quiz, $quizObj->quiz_id, __('Edit this quiz...', 'wp_courseware'), $quizObj->quiz_title, $quizObj->quiz_id, $quizObj->quiz_desc); } printf('<li id="wpcw_unit_%d" class="wpcw_dragable_unit_item"> <div><a href="%s&post=%d" target="_blank" title="%s">%s (ID: %d)</a></div> <div class="wpcw_dragable_quiz_holder"><ol class="wpcw_dragable_quizzes_connected wpcw_one_only">%s</ol></div> </li>', $unassUnit->ID, $modifyURL_unit, $unassUnit->ID, __('Edit this unit...', 'wp_courseware'), $unassUnit->post_title, $unassUnit->ID, $existingQuiz); } } printf('</ol></li>'); } printf('</ol>'); } else { _e('No modules yet.', 'wp_courseware'); } ?> <div id="wpcw_sticky_bar" style="display: none"> <div id="wpcw_sticky_bar_inner"> <a href="#" id="wpcw_dragable_modules_save" class="button-primary"><?php _e('Save Changes to Ordering', 'wp_courseware'); ?> </a> <span id="wpcw_sticky_bar_status" title="<?php _e('Ordering has changed. Ready to save changes?', 'wp_courseware'); ?> "></span> </div> </div> <?php // Close overall wrapper printf('</div>'); $page->showPageFooter(); }
/** * Displays the Assigned courses for the i4_assigned_courses shortcode * * @since 1.0.0 */ function i4_assigned_courses() { global $wpcwdb, $wpdb; $wpdb->show_errors(); $user_id = get_current_user_id(); $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, $user_id); // Break out if the user doesn't have access to this course if (!$this->I4_LMS_User_Can_Access($course->course_id, $user_id)) { continue; } //Retrieve the modules for the users course $modules = WPCW_courses_getModuleDetailsList($course->course_id); //Determine the % of course completion $i4_percent_completed = $this->i4_lms_percent_course_completed($course->course_id, $modules, $user_id); //Get a list of the completed units. We'll search the completed units array $i4_completed_units = $this->i4_get_completed_units($course->course_id, $user_id); printf(__('<div class="my-course-wrapper">')); printf(__('<div class="my-course-meta">')); printf(__('<div class="my-course-title" >')); printf(__('<h3 class="wpcw_tbl_progress_course">Course - %s</h3>'), $course->course_title); printf(__('</div> <!-- end my-course-title -->')); printf(__('<div class="my-course-pct-complete">%s%% Complete</div>'), $i4_percent_completed); printf(__('</div><!-- end course-meta -->')); printf('<div class="my-course-outline-wrapper">'); //Let's get the modules for the course if ($modules) { foreach ($modules as $module) { //get the units for the module $units = WPCW_units_getListOfUnits($module->module_id); //display the module title printf('<div class="my-course-module-title">'); printf(__('<p>%s</p>'), $module->module_title); printf('</div> <!-- end my-course-module-title -->'); //create a table for each of the units in the module printf('<table class="my-course-units-table">'); //iterate through the units for the module if ($units) { foreach ($units as $unit) { printf('<tr>'); printf('<td class="large-12 columns">'); printf('<a href="%s" title="%s"><i class="fa fa-play-circle-o"></i> %s</a>', get_the_permalink($unit->ID), $unit->post_title, $unit->post_title); // printf('</td>'); printf('<span class="right">'); //If the unit is in the completed units array, display the completed checkmark. if (in_array($unit->ID, $i4_completed_units)) { printf('<i class="fa fa-check font-success completed-icon"></i>'); } else { printf(__('<a class="button round tiny blue" title="Begin %s" href="%s">Begin</a>'), $unit->post_title, get_the_permalink($unit->ID)); } printf('</span></td>'); printf('</tr>'); } } printf('</table> <!-- my-course-units-table -->'); } } /* 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 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') ); } // Survey not taken yet else { printf('<td class="wpcw_center">%s</td>', __('Pending', 'wp_courseware')); } } // Quiz - show correct answers. 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') ); } // end of if printf('<td class="wpcw_tbl_progress_completed">%s</td>' // Quiz not taken yet else { printf('<td class="wpcw_center">%s</td>', __('Pending', 'wp_courseware')); } } // end of if survey } // end of if $quizDetails // No quiz for this unit 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>'); if ($i4_percent_completed == 100) { printf('<div class="my-courses-congrats">Congrats, Course Complete!</div>'); } printf('</div> <!--end my-course-outline-wrapper -->'); printf('</div> <!-- end my-course-wrapper -->'); // Track number of courses user can actually access $courseCount++; } //end foreach courses as course // Course is not allowed to access any courses. So show a meaningful message. if ($courseCount == 0) { printf('You are not currently enrolled in a course. Please contact your Care Coordinator for assistance.', 'wp_courseware'); } } }
/** * Generate a course list for resetting the progress for a user. * * @param $fieldName String The name to use for the name attribute for this dropdown. * @param $courseIDList Array If specified, this is a list of IDs to determine which courses to use in the reset box. * @param $blankMessage String the message to show if there are no courses. * @param $addBlank String Use this string as the first item in the dropdown. * @param $cssID String The CSS ID to use for the select box. * @param $cssClass String The CSS class to use for the select box. * * @return String The course reset dropdown box. */ function WPCW_courses_getCourseResetDropdown($fieldName, $courseIDList = false, $blankMessage, $addBlank, $cssID, $cssClass) { $selectDetails = array('' => $addBlank); // Need all courses $courseList = WPCW_courses_getCourseList(); if (!empty($courseList)) { $blankCount = 2; foreach ($courseList as $courseID => $aCourse) { // Filter out unwanted courses. if (is_array($courseIDList) && !in_array($courseID, $courseIDList)) { continue; } // Have sentinel of course_ to identify a course. $selectDetails['course_' . $courseID] = $aCourse; // Now we add the modules for this course $moduleList = WPCW_courses_getModuleDetailsList($courseID); if (!empty($moduleList)) { foreach ($moduleList as $moduleID => $moduleDetails) { // Now we add the units for this course $units = WPCW_units_getListOfUnits($moduleID); if (!empty($units)) { // Only add a module if it has units, to make resetting easier. $selectDetails['module_' . $moduleID] = sprintf(' - %s %d: %s', __('Module', 'wp_courseware'), $moduleDetails->module_number, $moduleDetails->module_title); foreach ($units as $unitID => $unitDetails) { $selectDetails['unit_' . $unitID] = sprintf(' -- %s %d: %s', __('Unit', 'wp_courseware'), $unitDetails->unit_meta->unit_number, $unitDetails->post_title); } } // end of unit list check } // end of foreach module } // end of module list check // Add a blank sentinel to space out courses. $paddingKey = str_pad(false, $blankCount++, ' '); $selectDetails[$paddingKey] = ' '; } } // No courses... show meaningful message to the trainer. if (count($selectDetails) == 1) { $selectDetails[' '] = $blankMessage; } // Generate the select box. Use the $cssID as the name of the field too. return WPCW_forms_createDropdown($fieldName, $selectDetails, false, $cssID, $cssClass); }