/** * 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. }
/** * Delete a module and disassociating of the units that it contains. * * @param Object $moduleDetails The details of the module to delete. */ function WPCW_modules_deleteModule($moduleDetails) { if (!$moduleDetails) { return; } global $wpdb, $wpcwdb; $wpdb->show_errors(); // Remove association with all units for this module $unitList = WPCW_units_getListOfUnits($moduleDetails->module_id); if ($unitList) { // Unassociate units from this module $SQL = $wpdb->prepare("\n\t\t\tUPDATE {$wpcwdb->units_meta}\n\t\t\t SET unit_order = 0, parent_module_id = 0, parent_course_id = 0, unit_number = 0\n\t\t\tWHERE parent_module_id = %d\n\t\t", $moduleDetails->module_id); // Update database with new association and ordering. foreach ($unitList as $unitID => $unitObj) { $wpdb->query($SQL); // Update post meta to remove associated module detail update_post_meta($unitID, 'wpcw_associated_module', 0); // Remove progress for this unit, since unit is now unassociated. $SQL = $wpdb->prepare("\n\t\t\t\tDELETE FROM {$wpcwdb->user_progress}\n\t\t\t\tWHERE unit_id = %d\n\t\t\t", $unitID); $wpdb->query($SQL); } } // Perform module deletion here. $wpdb->query($SQL = $wpdb->prepare("\n\t\t\t\tDELETE FROM {$wpcwdb->modules}\n\t\t\t\tWHERE module_id = %d\n\t\t\t", $moduleDetails->module_id)); // Modules have changed for this course, update numbering do_action('wpcw_modules_modified', $moduleDetails->parent_course_id); // Course has been updated, update the progress details $courseDetails = WPCW_courses_getCourseDetails($moduleDetails->parent_course_id); if ($courseDetails) { do_action('wpcw_course_details_updated', $courseDetails); } // Trigger event that module has been deleted do_action('wpcw_module_deleted', $moduleDetails); }
/** * 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(); }
/** * Display the percentage of the course that the user has completed * * @param INT $course_id for the users course * @param Object $modules the users modules for their course * @param INT $user_id the users ID */ function i4_lms_percent_course_completed($course_id, $modules, $user_id) { global $wpcwdb, $wpdb; $wpdb->show_errors(); $num_units = 0; $num_units_completed = 0; //Get the number of completed units for the course by the user $num_units_completed = $this->i4_get_num_completed_units($course_id, $user_id); if ($modules) { foreach ($modules as $module) { //Get the units for the module $units = WPCW_units_getListOfUnits($module->module_id); foreach ($units as $unit) { $num_units++; } } } //Do some Math here to get the percentage of the course completion. $percent_completed = $num_units_completed / $num_units * 100; //Let's keep the percentage to 2 decimal points. $percent_completed = number_format($percent_completed, 2, '.', ''); return $percent_completed; }
/** * Function that allows a module to be created or edited. */ function WPCW_showPage_ModifyModule_load() { $page = new PageBuilder(true); $moduleDetails = false; $moduleID = false; $adding = false; // Trying to edit a course if (isset($_GET['module_id'])) { $moduleID = $_GET['module_id'] + 0; $moduleDetails = WPCW_modules_getModuleDetails($moduleID); // Abort if module not found. if (!$moduleDetails) { $page->showPageHeader(__('Edit Module', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); $page->showMessage(__('Sorry, but that module could not be found.', 'wp_courseware'), true); $page->showPageFooter(); return; } else { $page->showPageHeader(__('Edit Module', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); } } else { $page->showPageHeader(__('Add Module', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); $adding = true; } global $wpcwdb; $formDetails = array('module_title' => array('label' => __('Module Title', 'wp_courseware'), 'type' => 'text', 'required' => true, 'cssclass' => 'wpcw_module_title', 'desc' => __('The title of your module. You <b>do not need to number the modules</b> - this is done automatically based on the order that they are arranged.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 150, 'minlen' => 1, 'regexp' => '/^[^<>]+$/', 'error' => __('Please specify a name for your module, up to a maximum of 150 characters, just no angled brackets (< or >). Your trainees will be able to see this module title.', 'wp_courseware'))), 'parent_course_id' => array('label' => __('Associated Course', 'wp_courseware'), 'type' => 'select', 'required' => true, 'cssclass' => 'wpcw_associated_course', 'desc' => __('The associated training course that this module belongs to.', 'wp_courseware'), 'data' => WPCW_courses_getCourseList(__('-- Select a Training Course --', 'wp_courseware'))), 'module_desc' => array('label' => __('Module Description', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_module_desc', 'desc' => __('The description of this module. Your trainees will be able to see this module description.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 5000, 'minlen' => 1, 'error' => __('Please limit the description of your module to 5000 characters.', 'wp_courseware')))); $form = new RecordsForm($formDetails, $wpcwdb->modules, 'module_id'); $form->customFormErrorMsg = __('Sorry, but unfortunately there were some errors saving the module details. Please fix the errors and try again.', 'wp_courseware'); $form->setAllTranslationStrings(WPCW_forms_getTranslationStrings()); // Useful place to go $directionMsg = '<br/></br>' . sprintf(__('Do you want to return to the <a href="%s">course summary page</a>?', 'wp_courseware'), admin_url('admin.php?page=WPCW_wp_courseware')); // Override success messages $form->msg_record_created = __('Module details successfully created.', 'wp_courseware') . $directionMsg; $form->msg_record_updated = __('Module details successfully updated.', 'wp_courseware') . $directionMsg; $form->setPrimaryKeyValue($moduleID); $form->setSaveButtonLabel(__('Save ALL Details', 'wp_courseware')); // See if we have a course ID to pre-set. if ($adding && ($courseID = WPCW_arrays_getValue($_GET, 'course_id'))) { $form->loadDefaults(array('parent_course_id' => $courseID)); } // Call to re-order modules once they've been created $form->afterSaveFunction = 'WPCW_actions_modules_afterModuleSaved_formHook'; $form->show(); $page->showPageMiddle('20%'); // Editing a module? if ($moduleDetails) { // ### Include a link to delete the module $page->openPane('wpcw-deletion-module', __('Delete Module?', 'wp_courseware')); printf('<a href="%s&action=delete_module&module_id=%d" class="wpcw_delete_item" title="%s">%s</a>', admin_url('admin.php?page=WPCW_wp_courseware'), $moduleID, __("Are you sure you want to delete the this module?\n\nThis CANNOT be undone!", 'wp_courseware'), __('Delete this Module', 'wp_courseware')); printf('<p>%s</p>', __('Units will <b>not</b> be deleted, they will <b>just be disassociated</b> from this module.', 'wp_courseware')); $page->closePane(); // #### Show a list of all sub-units $page->openPane('wpcw-units-module', __('Units in this Module', 'wp_courseware')); $unitList = WPCW_units_getListOfUnits($moduleID); if ($unitList) { printf('<ul class="wpcw_unit_list">'); foreach ($unitList as $unitID => $unitObj) { printf('<li>%s %d - %s</li>', __('Unit', 'wp_courseware'), $unitObj->unit_meta->unit_number, $unitObj->post_title); } printf('</ul>'); } else { printf('<p>%s</p>', __('There are currently no units in this module.', 'wp_courseware')); } } $page->showPageFooter(); }
/** * 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); }