/** * Shows a detailed summary of the user's quiz or survey answers. */ function WPCW_showPage_UserProgess_quizAnswers_load() { global $wpcwdb, $wpdb; $wpdb->show_errors(); $page = new PageBuilder(false); $page->showPageHeader(__('Detailed User Quiz/Survey Results', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); $userID = WPCW_arrays_getValue($_GET, 'user_id') + 0; $unitID = WPCW_arrays_getValue($_GET, 'unit_id') + 0; $quizID = WPCW_arrays_getValue($_GET, 'quiz_id') + 0; // Create a link back to the detailed user progress, and back to all users. printf('<div class="wpcw_button_group">'); // Link back to all user summary printf('<a href="%s" class="button-secondary">%s</a> ', admin_url('users.php'), __('« Return to User Summary', 'wp_courseware')); if ($userDetails = get_userdata($userID)) { // Link back to user's personal summary printf('<a href="%s&user_id=%d" class="button-secondary">%s</a> ', admin_url('users.php?page=WPCW_showPage_UserProgess'), $userDetails->ID, sprintf(__('« Return to <b>%s\'s</b> Progress Report', 'wp_courseware'), $userDetails->display_name)); } // Try to get the full detailed results. $results = WPCW_quizzes_getUserResultsForQuiz($userID, $unitID, $quizID); // No results, so abort. if (!$results) { // Close the button wrapper for above early printf('</div>'); // .wpcw_button_group $page->showMessage(__('Sorry, but no results could be found.', 'wp_courseware'), true); $page->showPageFooter(); return; } // Could potentially have an issue where the quiz has been deleted // but the data exists.. small chance though. $quizDetails = WPCW_quizzes_getQuizDetails($quizID, true, true, $userID); // Extra button - return to gradebook printf('<a href="%s&course_id=%d" class="button-secondary">%s</a> ', admin_url('admin.php?page=WPCW_showPage_GradeBook'), $quizDetails->parent_course_id, __("« Return to Gradebook", 'wp_courseware')); printf('</div>'); // .wpcw_button_group // #### 1 - Handle grades being updated $results = WPCW_showPage_UserProgess_quizAnswers_handingGrading($quizDetails, $results, $page, $userID, $unitID); // #### 2A - Check if next action for user has been triggered by the admin. $results = WPCW_showPage_UserProgess_quizAnswers_whatsNext_savePreferences($quizDetails, $results, $page, $userID, $unitID); // #### 2B - Handle telling admin what's next WPCW_showPage_UserProgess_quizAnswers_whatsNext($quizDetails, $results, $page, $userID, $unitID); //Ê#### 3 - Handle sending emails if something has changed. if (isset($results->sendOutEmails) && $results->sendOutEmails) { $extraDetail = isset($results->extraEmailDetail) ? $results->extraEmailDetail : ''; // Only called if the quiz was graded. if (isset($results->quiz_has_just_been_graded) && $results->quiz_has_just_been_graded) { // Need to call the action anyway, but any functions hanging off this // should check if the admin wants users to have notifications or not. do_action('wpcw_quiz_graded', $userID, $quizDetails, number_format($results->quiz_grade, 1), $extraDetail); } $courseDetails = WPCW_courses_getCourseDetails($quizDetails->parent_course_id); if ($courseDetails->email_quiz_grade_option == 'send_email') { // Message is only if quiz has been graded. if (isset($results->quiz_has_just_been_graded) && $results->quiz_has_just_been_graded) { $page->showMessage(__('The user has been sent an email with their grade for this course.', 'wp_courseware')); } } } // #### - Table 1 - Overview printf('<h3>%s</h3>', __('Quiz/Survey Overview', 'wp_courseware')); $tbl = new TableBuilder(); $tbl->attributes = array('id' => 'wpcw_tbl_progress_quiz_info', 'class' => 'widefat wpcw_tbl'); $tblCol = new TableColumn(false, 'quiz_label'); $tblCol->cellClass = 'wpcw_tbl_label'; $tbl->addColumn($tblCol); $tblCol = new TableColumn(false, 'quiz_detail'); $tbl->addColumn($tblCol); // These are the base details for the quiz to show. $summaryData = array(__('Quiz Title', 'wp_courseware') => $quizDetails->quiz_title, __('Quiz Description', 'wp_courseware') => $quizDetails->quiz_desc, __('Quiz Type', 'wp_courseware') => WPCW_quizzes_getQuizTypeName($quizDetails->quiz_type), __('No. of Questions', 'wp_courseware') => $results->quiz_question_total, __('Completed Date', 'wp_courseware') => __('About', 'wp_courseware') . ' ' . human_time_diff($results->quiz_completed_date_ts) . ' ' . __('ago', 'wp_courseware') . '<br/><small>(' . date('D jS M Y \\a\\t H:i:s', $results->quiz_completed_date_ts) . ')</small>', __('Number of Quiz Attempts', 'wp_courseware') => $results->attempt_count, __('Permitted Quiz Attempts', 'wp_courseware') => -1 == $quizDetails->quiz_attempts_allowed ? __('Unlimited', 'wp_courseware') : $quizDetails->quiz_attempts_allowed); // Quiz details relating to score, etc. if ('survey' != $quizDetails->quiz_type) { $summaryData[__('Pass Mark', 'wp_courseware')] = $quizDetails->quiz_pass_mark . '%'; // Still got items to grade if ($results->quiz_needs_marking > 0) { $summaryData[__('No. of Questions to Grade', 'wp_courseware')] = '<span class="wpcw_status_info wpcw_icon_pending">' . $results->quiz_needs_marking . '</span>'; $summaryData[__('Overall Grade', 'wp_courseware')] = '<span class="wpcw_status_info wpcw_icon_pending">' . __('Awaiting Final Grading', 'wp_courseware') . '</span>'; } else { $summaryData[__('No. of Question to Grade', 'wp_courseware')] = '-'; // Show if PASSED or FAILED with the overall grade. $gradeData = false; if ($results->quiz_grade >= $quizDetails->quiz_pass_mark) { $gradeData = sprintf('<span class="wpcw_tbl_progress_quiz_overall wpcw_question_yesno_status wpcw_question_yes">%s%% %s</span>', number_format($results->quiz_grade, 1), __('Passed', 'wp_courseware')); } else { $gradeData = sprintf('<span class="wpcw_tbl_progress_quiz_overall wpcw_question_yesno_status wpcw_question_no">%s%% %s</span>', number_format($results->quiz_grade, 1), __('Failed', 'wp_courseware')); } $summaryData[__('Overall Grade', 'wp_courseware')] = $gradeData; } } foreach ($summaryData as $label => $data) { $tbl->addRow(array('quiz_label' => $label . ':', 'quiz_detail' => $data)); } echo $tbl->toString(); // ### 4 - Form Code - to allow instructor to send data back to printf('<form method="POST" id="wpcw_tbl_progress_quiz_grading_form">'); printf('<input type="hidden" name="grade_answers_submitted" value="true">'); // ### 5 - Table 2 - Each Specific Quiz $questionNumber = 0; if ($results->quiz_data && count($results->quiz_data) > 0) { foreach ($results->quiz_data as $questionID => $answer) { $data = $answer; // Get the question type if (isset($quizDetails->questions[$questionID])) { // Store as object for easy reference. $quObj = $quizDetails->questions[$questionID]; // Render the question as a table. printf('<h3>%s #%d - %s</h3>', __('Question', 'wp_courseware'), ++$questionNumber, $quObj->question_question); $tbl = new TableBuilder(); $tbl->attributes = array('id' => 'wpcw_tbl_progress_quiz_info', 'class' => 'widefat wpcw_tbl wpcw_tbl_progress_quiz_answers_' . $quObj->question_type); $tblCol = new TableColumn(false, 'quiz_label'); $tblCol->cellClass = 'wpcw_tbl_label'; $tbl->addColumn($tblCol); $tblCol = new TableColumn(false, 'quiz_detail'); $tbl->addColumn($tblCol); $theirAnswer = false; switch ($quObj->question_type) { case 'truefalse': case 'multi': $theirAnswer = $answer['their_answer']; break; // File Upload - create a download link // File Upload - create a download link case 'upload': $theirAnswer = sprintf('<a href="%s%s" target="_blank" class="button-primary">%s .%s %s (%s)</a>', WP_CONTENT_URL, $answer['their_answer'], __('Open', 'wp_courseware'), pathinfo($answer['their_answer'], PATHINFO_EXTENSION), __('File', 'wp_courseware'), WPCW_files_getFileSize_human($answer['their_answer'])); break; // Open Ended - Wrap in span tags, to cap the size of the field, and format new lines. // Open Ended - Wrap in span tags, to cap the size of the field, and format new lines. case 'open': $theirAnswer = '<span class="wpcw_q_answer_open_wrap"><textarea readonly>' . $data['their_answer'] . '</textarea></span>'; break; } // end of $theirAnswer check $summaryData = array(__('Type', 'wp_courseware') => array('data' => WPCW_quizzes_getQuestionTypeName($quObj->question_type), 'cssclass' => ''), __('Their Answer', 'wp_courseware') => array('data' => $theirAnswer, 'cssclass' => '')); // Just for quizzes - show answers/grade if ('survey' != $quizDetails->quiz_type) { switch ($quObj->question_type) { case 'truefalse': case 'multi': // The right answer... $summaryData[__('Correct Answer', 'wp_courseware')] = array('data' => $answer['correct'], 'cssclass' => ''); // Did they get it right? $getItRight = sprintf('<span class="wpcw_question_yesno_status wpcw_question_%s">%s</span>', $answer['got_right'], 'yes' == $answer['got_right'] ? __('Yes', 'wp_courseware') : __('No', 'wp_courseware')); $summaryData[__('Did they get it right?', 'wp_courseware')] = array('data' => $getItRight, 'cssclass' => ''); break; case 'upload': case 'open': $gradeHTML = false; $theirGrade = WPCW_arrays_getValue($answer, 'their_grade'); // Not graded - show select box. if ($theirGrade == 0) { $cssClass = 'wpcw_grade_needs_grading'; } else { $cssClass = 'wpcw_grade_already_graded'; $gradeHTML = sprintf('<span class="wpcw_grade_view">%d%% <a href="#">(%s)</a></span>', $theirGrade, __('Click to edit', 'wp_courseware')); } // Not graded yet, allow admin to grade the quiz, or change // the grading later if they want to. $gradeHTML .= WPCW_forms_createDropdown('grade_quiz_' . $quObj->question_id, WPCW_quizzes_getPercentageList(__('-- Select a grade --', 'wp_courseware')), $theirGrade, false, 'wpcw_tbl_progress_quiz_answers_grade'); $summaryData[__('Their Grade', 'wp_courseware')] = array('data' => $gradeHTML, 'cssclass' => $cssClass); break; } } // Check of showing the right answer. foreach ($summaryData as $label => $data) { $tbl->addRow(array('quiz_label' => $label . ':', 'quiz_detail' => $data['data']), $data['cssclass']); } echo $tbl->toString(); } // end if (isset($quizDetails->questions[$questionID])) } // foreach ($results->quiz_data as $questionID => $answer) } printf('</form>'); // Shows a bar that pops up, allowing the user to easily save all grades that have changed. ?> <div id="wpcw_sticky_bar" style="display: none"> <div id="wpcw_sticky_bar_inner"> <a href="#" id="wpcw_tbl_progress_quiz_grading_updated" class="button-primary"><?php _e('Save Changes to Grades', 'wp_courseware'); ?> </a> <span id="wpcw_sticky_bar_status" title="<?php _e('Grades have been changed. Ready to save changes?', 'wp_courseware'); ?> "></span> </div> </div> <br/><br/><br/><br/> <?php $page->showPageFooter(); }
/** * 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(); }
/** * 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(); }
/** * Shows the page listing the available groups. */ function WPPortfolio_show_website_groups() { ?> <div class="wrap"> <div id="icon-edit" class="icon32"> <br/> </div> <h2><?php _e('Website Groups', 'wp-portfolio'); ?> </h2> <br/> <?php global $wpdb; $groups_table = $wpdb->prefix . TABLE_WEBSITE_GROUPS; $websites_table = $wpdb->prefix . TABLE_WEBSITES; // Get group ID $groupid = false; if (isset($_GET['groupid'])) { $groupid = $_GET['groupid'] + 0; } // ### DELETE ### Check if we're deleting a group if ($groupid > 0 && isset($_GET['delete'])) { // Now check that ID actually relates to a real group $groupdetails = WPPortfolio_getGroupDetails($groupid); // If group doesn't really exist, then stop. if (count($groupdetails) == 0) { WPPortfolio_showMessage(sprintf(__('Sorry, but no group with that ID could be found. Please click <a href="%s">here</a> to return to the list of groups.', 'wp-portfolio'), WPP_GROUP_SUMMARY), true); return; } // Count the number of websites in this group and how many groups exist $website_count = $wpdb->get_var("SELECT COUNT(*) FROM {$websites_table} WHERE sitegroup = '" . $wpdb->escape($groupdetails['groupid']) . "'"); $group_count = $wpdb->get_var("SELECT COUNT(*) FROM {$groups_table}"); $groupname = stripcslashes($groupdetails['groupname']); // Check that group doesn't have a load of websites assigned to it. if ($website_count > 0) { WPPortfolio_showMessage(sprintf(__("Sorry, the group '%s' still contains <b>{$website_count}</b> websites. Please ensure the group is empty before deleting it.", 'wp-portfolio'), $groupname)); return; } // If we're deleting the last group, don't let it happen if ($group_count == 1) { WPPortfolio_showMessage(sprintf(__("Sorry, but there needs to be at least 1 group in the portfolio. Please add a new group before deleting %s", 'wp-portfolio'), $groupname)); return; } // OK, got this far, confirm we want to delete. if (isset($_GET['confirm'])) { $delete_group = "DELETE FROM {$groups_table} WHERE groupid = '" . $wpdb->escape($groupid) . "' LIMIT 1"; if ($wpdb->query($delete_group)) { WPPortfolio_showMessage(__("Group was successfully deleted.", 'wp-portfolio')); } else { WPPortfolio_showMessage(__("Sorry, but an unknown error occured whist trying to delete the selected group from the portfolio.", 'wp-portfolio'), true); } } else { $message = sprintf(__('Are you sure you want to delete the group \'%1$s\' from your portfolio?<br/><br/> <a href="%2$s">Yes, delete.</a> <a href="%3$s">NO!</a>', 'wp-portfolio'), $groupname, WPP_GROUP_SUMMARY . '&delete=yes&confirm=yes&groupid=' . $groupid, WPP_GROUP_SUMMARY); WPPortfolio_showMessage($message); return; } } // Get website details, merge with group details $SQL = "SELECT * FROM {$groups_table}\r\n\t \t\tORDER BY grouporder, groupname"; // DEBUG Uncomment if needed // $wpdb->show_errors(); $groups = $wpdb->get_results($SQL, OBJECT); // Only show table if there are any results. if ($groups) { $table = new TableBuilder(); $table->attributes = array("id" => "wpptable"); $column = new TableColumn(__("ID", 'wp-portfolio'), "id"); $column->cellClass = "wpp-id"; $table->addColumn($column); $column = new TableColumn(__("Name", 'wp-portfolio'), "name"); $column->cellClass = "wpp-name"; $table->addColumn($column); $column = new TableColumn(__("Description", 'wp-portfolio'), "description"); $table->addColumn($column); $column = new TableColumn(__("# Websites", 'wp-portfolio'), "websitecount"); $column->cellClass = "wpp-small wpp-center"; $table->addColumn($column); $column = new TableColumn(__("Ordering", 'wp-portfolio'), "ordering"); $column->cellClass = "wpp-small wpp-center"; $table->addColumn($column); $column = new TableColumn(__("Action", 'wp-portfolio'), "action"); $column->cellClass = "wpp-small action-links"; $column->headerClass = "action-links"; $table->addColumn($column); echo '<p>' . __('The websites will be rendered in groups in the order shown in the table.', 'wp-portfolio') . '</p>'; foreach ($groups as $groupdetails) { $groupClickable = sprintf('<a href="' . WPP_WEBSITE_SUMMARY . '&groupid=' . $groupdetails->groupid . '" title="' . __('Show websites only in the \'%s\' group">', 'wp-portfolio'), $groupdetails->groupname); // Count websites in this group $website_count = $wpdb->get_var("SELECT COUNT(*) FROM {$websites_table} WHERE sitegroup = '" . $wpdb->escape($groupdetails->groupid) . "'"); $rowdata = array(); $rowdata['id'] = $groupdetails->groupid; $rowdata['name'] = $groupClickable . stripslashes($groupdetails->groupname) . '</a>'; $rowdata['description'] = stripslashes($groupdetails->groupdescription); $rowdata['websitecount'] = $groupClickable . $website_count . ($website_count == 1 ? ' website' : ' websites') . "</a>"; $rowdata['ordering'] = $groupdetails->grouporder; $rowdata['action'] = '<a href="' . WPP_GROUP_SUMMARY . '&delete=yes&groupid=' . $groupdetails->groupid . '">' . __('Delete', 'wp-portfolio') . '</a> | ' . '<a href="' . WPP_MODIFY_GROUP . '&editmode=edit&groupid=' . $groupdetails->groupid . '">' . __('Edit', 'wp-portfolio') . '</a></td>'; $table->addRow($rowdata); } // Finally show table echo $table->toString(); echo "<br/>"; } else { WPPortfolio_showMessage(__("There are currently no groups in the portfolio.", 'wp-portfolio'), true); } ?> </div> <?php }
/** * Page that shows the overview of mapping for the levels to courses. * @param PageBuilder $page The current page object. */ private function showMembershipMappingLevels_overview($page) { // Handle the detection of the membership plugin before doing anything else. if (!$this->found_membershipTool()) { $page->showPageFooter(); return; } // Try to show the level data $levelData = $this->getMembershipLevels_cached(); if ($levelData) { // Create the table to show the data $table = new TableBuilder(); $table->attributes = array('class' => 'wpcw_tbl widefat', 'id' => 'wpcw_members_tbl'); $col = new TableColumn(__('Level ID', 'wp_courseware'), 'wpcw_members_id'); $table->addColumn($col); $col = new TableColumn(__('Level Name', 'wp_courseware'), 'wpcw_members_name'); $table->addColumn($col); $col = new TableColumn(__('Users at this level can access:', 'wp_courseware'), 'wpcw_members_levels'); $table->addColumn($col); $col = new TableColumn(__('Actions', 'wp_courseware'), 'wpcw_members_actions'); $table->addColumn($col); $odd = false; // Work out the base URL for the overview page $baseURL = admin_url('admin.php?page=' . $this->extensionID); // The list of courses that are currently on the system. $courses = WPCW_courses_getCourseList(false); // Add actual level data foreach ($levelData as $id => $levelDatum) { $data = array(); $data['wpcw_members_id'] = $levelDatum['id']; $data['wpcw_members_name'] = $levelDatum['name']; // Get list of courses already associated with level. $courseListInDB = $this->getCourseAccessListForLevel($levelDatum['id']); if ($courses) { $data['wpcw_members_levels'] = '<ul class="wpcw_tickitems">'; // Show which courses will be added to users created at this level. foreach ($courses as $courseID => $courseName) { $data['wpcw_members_levels'] .= sprintf('<li class="wpcw_%s">%s</li>', isset($courseListInDB[$courseID]) ? 'enabled' : 'disabled', $courseName); } $data['wpcw_members_levels'] .= '</ul>'; } else { $data['wpcw_members_levels'] = __('There are no courses yet.', 'wp_courseware'); } // Buttons to edit the permissions $data['wpcw_members_actions'] = sprintf('<a href="%s&level_id=%s" class="button-secondary">%s</a>', $baseURL, $levelDatum['id'], __('Edit Course Access Settings', 'wp_courseware')); $odd = !$odd; $table->addRow($data, $odd ? 'alternate' : ''); } echo $table->toString(); } else { $page->showMessage(sprintf(__('No membership levels were found for %s.', 'wp_courseware'), $this->extensionName), true); } }
/** * Shows the page where the caching settings and information is shown. */ function STWWT_showPage_ErrorLogs() { // To add at some point - shows if the cache directory is writeable. //$cachePath = STWWT_plugin_getCacheDirectory(); //echo $isWriteable = (file_exists($cachePath) && is_dir($cachePath) && is_writable($cachePath)); global $wpdb; $wpdb->show_errors(); $error_log = $wpdb->prefix . STWWT_TABLE_ERRORS; $page = new PageBuilder(false); $page->showPageHeader(__('Shrink The Web - Website Thumbnails - Error Logs', 'stwwt'), '70%'); // Check for clear of logs if (isset($_POST['stwwt-clear-logs'])) { // Delete error thumbnails STWWT_cache_emptyCache(true); $SQL = "TRUNCATE {$error_log}"; $wpdb->query($SQL); $page->showMessage("Debug logs have successfully been emptied."); } // Refresh and Clear Buttons ?> <form class="stwwt-button-right" method="post" action="<?php echo str_replace('%7E', '~', $_SERVER['REQUEST_URI']); ?> "> <input type="submit" name="stwwt-refresh-logs" value="Refresh Logs" class="button-primary" /> <input type="submit" name="stwwt-clear-logs" value="Clear Logs" class="button-secondary" /> <div class="stwwt-clear"></div> </form> <?php $SQL = "SELECT *, UNIX_TIMESTAMP(request_date) AS request_date_ts\r\n\t\t\t\tFROM {$error_log}\r\n\t\t\t\tORDER BY request_date DESC\r\n\t\t\t\tLIMIT 50\r\n\t\t\t\t"; $wpdb->show_errors(); $logMsgs = $wpdb->get_results($SQL, OBJECT); if ($logMsgs) { printf('<div id="stwwt_error_count">Showing a total of <b>%d</b> log messages.</div>', $wpdb->num_rows); ?> <p>All <b>errors are cached for 12 hours</b> so that your thumbnail allowance with STW does not get used up if you have persistent errors. If you've <b>had errors</b>, and you've <b>now fixed them</b>, you can click on the '<b>Clear Logs</b>' button on the right to <b>flush the error cache</b> and re-attempt to fetch a thumbnail.</p> <?php $table = new TableBuilder(); $table->attributes = array("id" => "stwwt_error_log"); $column = new TableColumn("ID", "id"); $column->cellClass = "stwwt_id"; $table->addColumn($column); $column = new TableColumn("Result", "request_result"); $column->cellClass = "stwwt_result"; $table->addColumn($column); $column = new TableColumn("Requested URL", "request_url"); $column->cellClass = "stwwt_url"; $table->addColumn($column); $column = new TableColumn("Type", "request_type"); $column->cellClass = "stwwt_type"; $table->addColumn($column); $column = new TableColumn("Request Date", "request_date"); $column->cellClass = "stwwt_request-date"; $table->addColumn($column); $column = new TableColumn("Detail", "request_detail"); $column->cellClass = "stwwt_detail"; $table->addColumn($column); foreach ($logMsgs as $logDetail) { $rowdata = array(); $rowdata['id'] = $logDetail->logid; $rowdata['request_url'] = $logDetail->request_url; $rowdata['request_type'] = $logDetail->request_type; $rowdata['request_result'] = '<span>' . ($logDetail->request_result == 1 ? 'Success' : 'Error') . '</span>'; $rowdata['request_date'] = $logDetail->request_date . '<br/>' . 'about ' . human_time_diff($logDetail->request_date_ts) . ' ago'; // Show arguments and details $rowdata['request_detail'] = sprintf('<span class="stwwt_debug_header">Error Message</span> <span class="stwwt_debug_info">%s</span>', $logDetail->request_error_msg); $rowdata['request_detail'] .= sprintf('<span class="stwwt_debug_header">Request Arguments</span> <span class="stwwt_debug_info">%s</span>', STWWT_debug_formatArray(unserialize($logDetail->request_args))); if ($logDetail->request_detail) { $rowdata['request_detail'] .= sprintf('<span class="stwwt_debug_header">Raw STW Response</span> <textarea class="stwwt_debug_raw" readonly="readonly">%s</textarea>', htmlentities($logDetail->request_detail)); } $table->addRow($rowdata, $logDetail->request_result == 1 ? 'stwwt_success' : 'stwwt_error'); } // Finally show table echo $table->toString(); echo "<br/>"; } else { printf('<div class="stwwt_clear"></div>'); $page->showMessage("There are currently no debug logs to show.", true); } $page->showPageFooter(); }
/** * Gradebook View - show the grade details for the users of the system. */ function WPCW_showPage_GradeBook_load() { $page = new PageBuilder(false); $courseDetails = false; $courseID = false; // Trying to view a specific course $courseDetails = false; if (isset($_GET['course_id'])) { $courseID = $_GET['course_id'] + 0; $courseDetails = WPCW_courses_getCourseDetails($courseID); } // Abort if course not found. if (!$courseDetails) { $page->showPageHeader(__('GradeBook', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); $page->showMessage(__('Sorry, but that course could not be found.', 'wp_courseware'), true); $page->showPageFooter(); return; } // Show title of this course $page->showPageHeader(__('GradeBook', 'wp_courseware') . ': ' . $courseDetails->course_title, '75%', WPCW_icon_getPageIconURL()); global $wpcwdb, $wpdb; $wpdb->show_errors(); // Need a list of all quizzes for this course, excluding surveys. $quizzesForCourse = WPCW_quizzes_getAllQuizzesForCourse($courseDetails->course_id); // Handle situation when there are no quizzes. if (!$quizzesForCourse) { $page->showMessage(__('There are no quizzes for this course, therefore no grade information to show.', 'wp_courseware'), true); $page->showPageFooter(); return; } // Create a simple list of IDs to use in SQL queries $quizIDList = array(); foreach ($quizzesForCourse as $singleQuiz) { $quizIDList[] = $singleQuiz->quiz_id; } // Convert list of IDs into an SQL list $quizIDListForSQL = '(' . implode(',', $quizIDList) . ')'; // Do we want certificates? $usingCertificates = 'use_certs' == $courseDetails->course_opt_use_certificate; // #### Handle checking if we're sending out any emails to users with their final grades // Called here so that any changes are reflected in the table using the code below. if ('email_grades' == WPCW_arrays_getValue($_GET, 'action')) { WPCW_showPage_GradeBook_handleFinalGradesEmail($courseDetails, $page); } // Get the requested page number $paging_pageWanted = WPCW_arrays_getValue($_GET, 'pagenum') + 0; if ($paging_pageWanted == 0) { $paging_pageWanted = 1; } // Need a count of how many there are to mark anyway, hence doing calculation. // Using COUNT DISTINCT so that we get a total of the different user IDs. // If we use GROUP BY, we end up with several rows of results. $userCount_toMark = $wpdb->get_var("\n\t\tSELECT COUNT(DISTINCT upq.user_id) AS user_count \n\t\tFROM {$wpcwdb->user_progress_quiz} upq\t\t\n\t\t\tLEFT JOIN {$wpdb->users} u ON u.ID = upq.user_id\t\t\t\t\t\t\t\t\t\t\t\n\t\tWHERE upq.quiz_id IN {$quizIDListForSQL}\n\t\t AND upq.quiz_needs_marking > 0\n\t\t AND u.ID IS NOT NULL\n\t\t AND quiz_is_latest = 'latest'\n\t\t"); // Count - all users for this course $userCount_all = $wpdb->get_var($wpdb->prepare("\n\t\tSELECT COUNT(*) AS user_count \n\t\tFROM {$wpcwdb->user_courses} uc\t\t\t\t\t\t\t\t\t\n\t\tLEFT JOIN {$wpdb->users} u ON u.ID = uc.user_id\n\t\tWHERE uc.course_id = %d\n\t\t AND u.ID IS NOT NULL\n\t\t", $courseDetails->course_id)); // Count - users who have completed the course. $userCount_completed = $wpdb->get_var($wpdb->prepare("\n\t\tSELECT COUNT(*) AS user_count \n\t\tFROM {$wpcwdb->user_courses} uc\t\t\t\t\t\t\t\t\t\n\t\tLEFT JOIN {$wpdb->users} u ON u.ID = uc.user_id\n\t\tWHERE uc.course_id = %d\n\t\t AND u.ID IS NOT NULL\n\t\t AND uc.course_progress = 100\n\t\t", $courseDetails->course_id)); // Count - all users that need their final grade. $userCount_needGrade = $wpdb->get_var($wpdb->prepare("\n\t\tSELECT COUNT(*) AS user_count \n\t\tFROM {$wpcwdb->user_courses} uc\t\t\t\t\t\t\t\t\t\n\t\tLEFT JOIN {$wpdb->users} u ON u.ID = uc.user_id\n\t\tWHERE uc.course_id = %d\n\t\t AND u.ID IS NOT NULL\n\t\t AND uc.course_progress = 100\n\t\t AND uc.course_final_grade_sent != 'sent'\n\t\t", $courseDetails->course_id)); // SQL Code used by filters below $coreSQL_allUsers = $wpdb->prepare("\n\t\t\tSELECT * \n\t\t\tFROM {$wpcwdb->user_courses} uc\t\t\t\t\t\t\t\t\t\n\t\t\t\tLEFT JOIN {$wpdb->users} u ON u.ID = uc.user_id\n\t\t\tWHERE uc.course_id = %d\n\t\t\t AND u.ID IS NOT NULL\t\t\t\n\t\t\t", $courseDetails->course_id); // The currently selected filter to determine what quizzes to show. $currentFilter = WPCW_arrays_getValue($_GET, 'filter'); switch ($currentFilter) { case 'to_mark': // Chooses all progress where there are questions that need grading. // Then group by user, so that we don't show the same user twice. // Not added join for certificates, since they can't be complete // if they've got stuff to be marked. $coreSQL = "\n\t\t\t\tSELECT * \n\t\t\t\tFROM {$wpcwdb->user_progress_quiz} upq\t\t\t\t\t\t\t\t\t\n\t\t\t\t\tLEFT JOIN {$wpdb->users} u ON u.ID = upq.user_id\t\t\t\t\t\n\t\t\t\t\tLEFT JOIN {$wpcwdb->user_courses} uc ON uc.user_id = upq.user_id\n\t\t\t\tWHERE upq.quiz_id IN {$quizIDListForSQL}\n\t\t\t\t AND upq.quiz_needs_marking > 0\n\t\t\t\t AND u.ID IS NOT NULL\n\t\t\t\t AND quiz_is_latest = 'latest'\n\t\t\t\tGROUP BY u.ID\t\t\t\t\t\t\t\t \n\t\t\t\t"; // No need to re-calculate, just re-use the number. $paging_totalCount = $userCount_toMark; break; // Completed the course // Completed the course case 'completed': // Same SQL as all users, but just filtering those with a progress of 100. $coreSQL = $coreSQL_allUsers . " \n\t\t\t\t\tAND uc.course_progress = 100\n\t\t\t\t"; // The total number of results to show - used for paging $paging_totalCount = $userCount_completed; break; // Completed the course // Completed the course case 'eligible_for_final_grade': // Same SQL as all users, but just filtering those with a progress of 100 AND // needing a final grade due to flag in course_progress. $coreSQL = $coreSQL_allUsers . " \n\t\t\t\t\tAND uc.course_progress = 100 \n\t\t\t\t\tAND course_final_grade_sent != 'sent'\n\t\t\t\t"; // The total number of results to show - used for paging $paging_totalCount = $userCount_needGrade; break; // Default to all users, regardless of what progress they've made // Default to all users, regardless of what progress they've made default: $currentFilter = 'all'; // Allow the query to be modified by other plugins $coreSQL_filteredUsers = apply_filters("wpcw_back_query_filter_gradebook_users", $coreSQL_allUsers, $courseDetails->course_id); // Select all users that exist for this course $coreSQL = $coreSQL_filteredUsers; // The total number of results to show - used for paging $paging_totalCount = $userCount_all; break; } // Generate page URL $summaryPageURL = admin_url('admin.php?page=WPCW_showPage_GradeBook&course_id=' . $courseDetails->course_id); $paging_resultsPerPage = 50; $paging_recordStart = ($paging_pageWanted - 1) * $paging_resultsPerPage + 1; $paging_recordEnd = $paging_pageWanted * $paging_resultsPerPage; $paging_pageCount = ceil($paging_totalCount / $paging_resultsPerPage); $paging_sqlStart = $paging_recordStart - 1; // Use the main SQL from above, but limit it and order by user's name. $SQL = "{$coreSQL}\n\t\t\tORDER BY display_name ASC\n\t\t\tLIMIT {$paging_sqlStart}, {$paging_resultsPerPage}"; // Generate paging code $baseURL = WPCW_urls_getURLWithParams($summaryPageURL, 'pagenum') . "&pagenum="; $paging = WPCW_tables_showPagination($baseURL, $paging_pageWanted, $paging_pageCount, $paging_totalCount, $paging_recordStart, $paging_recordEnd); $tbl = new TableBuilder(); $tbl->attributes = array('id' => 'wpcw_tbl_quiz_gradebook', 'class' => 'widefat wpcw_tbl'); $tblCol = new TableColumn(__('Learner Details', 'wp_courseware'), 'learner_details'); $tblCol->cellClass = "wpcw_learner_details"; $tbl->addColumn($tblCol); // ### Add the quiz data if ($quizzesForCourse) { // Show the overall progress for the course. $tblCol = new TableColumn(__('Overall Progress', 'wp_courseware'), 'course_progress'); //$tblCol->headerClass = "wpcw_center"; $tblCol->cellClass = "wpcw_grade_course_progress"; $tbl->addColumn($tblCol); // ### Create heading for cumulative data. $tblCol = new TableColumn(__('Cumulative Grade', 'wp_courseware'), 'quiz_cumulative'); $tblCol->headerClass = "wpcw_center"; $tblCol->cellClass = "wpcw_grade_summary wpcw_center"; $tbl->addColumn($tblCol); // ### Create heading for cumulative data. $tblCol = new TableColumn(__('Grade Sent?', 'wp_courseware'), 'grade_sent'); $tblCol->headerClass = "wpcw_center"; $tblCol->cellClass = "wpcw_grade_summary wpcw_center"; $tbl->addColumn($tblCol); // ### Create heading for cumulative data. if ($usingCertificates) { $tblCol = new TableColumn(__('Certificate Available?', 'wp_courseware'), 'certificate_available'); $tblCol->headerClass = "wpcw_center"; $tblCol->cellClass = "wpcw_grade_summary wpcw_center"; $tbl->addColumn($tblCol); } // ### Add main quiz scores foreach ($quizzesForCourse as $singleQuiz) { $tblCol = new TableColumn($singleQuiz->quiz_title, 'quiz_' . $singleQuiz->quiz_id); $tblCol->cellClass = "wpcw_center wpcw_quiz_grade"; $tblCol->headerClass = "wpcw_center wpcw_quiz_grade"; $tbl->addColumn($tblCol); } } $urlForQuizResultDetails = admin_url('users.php?page=WPCW_showPage_UserProgess_quizAnswers'); $userList = $wpdb->get_results($SQL); if (!$userList) { switch ($currentFilter) { case 'to_mark': $msg = __('There are currently no quizzes that need a manual grade.', 'wp_courseware'); break; case 'eligible_for_final_grade': $msg = __('There are currently no users that are eligible to receive their final grade.', 'wp_courseware'); break; case 'completed': $msg = __('There are currently no users that have completed the course.', 'wp_courseware'); break; default: $msg = __('There are currently no learners allocated to this course.', 'wp_courseware'); break; } // Create spanning item with message - number of quizzes + fixed columns. $rowDataObj = new RowDataSimple('wpcw_no_users wpcw_center', $msg, count($quizIDList) + 5); $tbl->addRowObj($rowDataObj); } else { // ### Format main row data and show it. $odd = false; foreach ($userList as $singleUser) { $data = array(); // Basic Details with avatar $data['learner_details'] = sprintf(' %s <span class="wpcw_col_cell_name">%s</span> <span class="wpcw_col_cell_username">%s</span> <span class="wpcw_col_cell_email"><a href="mailto:%s" target="_blank">%s</a></span></span> ', get_avatar($singleUser->ID, 48), $singleUser->display_name, $singleUser->user_login, $singleUser->user_email, $singleUser->user_email); // Get the user's progress for the quizzes. if ($quizzesForCourse) { $quizResults = WPCW_quizzes_getQuizResultsForUser($singleUser->ID, $quizIDListForSQL); // Track cumulative data $quizScoresSoFar = 0; $quizScoresSoFar_count = 0; // ### Now render results for each quiz foreach ($quizIDList as $aQuizID) { // Got progress data, process the result if (isset($quizResults[$aQuizID])) { // Extract results and unserialise the data array. $theResults = $quizResults[$aQuizID]; $theResults->quiz_data = maybe_unserialize($theResults->quiz_data); $quizDetailURL = sprintf('%s&user_id=%d&quiz_id=%d&unit_id=%d', $urlForQuizResultDetails, $singleUser->ID, $theResults->quiz_id, $theResults->unit_id); // We've got something that needs grading. So render link to where the quiz can be graded. if ($theResults->quiz_needs_marking > 0) { $data['quiz_' . $aQuizID] = sprintf('<span class="wpcw_grade_needs_grading"><a href="%s">%s</span>', $quizDetailURL, __('Manual Grade Required', 'wp_courseware')); } else { if ('quiz_fail_no_retakes' == $theResults->quiz_next_step_type) { $data['quiz_' . $aQuizID] = sprintf('<span class="wpcw_grade_needs_grading"><a href="%s">%s</span>', $quizDetailURL, __('Quiz Retakes Exhausted', 'wp_courseware')); } else { if ('incomplete' == $theResults->quiz_paging_status) { $data['quiz_' . $aQuizID] = '<span class="wpcw_grade_not_taken">' . __('In Progress', 'wp_courseware') . '</span>'; } else { // Use grade for cumulative grade $score = number_format($quizResults[$aQuizID]->quiz_grade, 1); $quizScoresSoFar += $score; $quizScoresSoFar_count++; // Render score and link to the full test data. $data['quiz_' . $aQuizID] = sprintf('<span class="wpcw_grade_valid"><a href="%s">%s%%</span>', $quizDetailURL, $score); } } } } else { $data['quiz_' . $aQuizID] = '<span class="wpcw_grade_not_taken">' . __('Not Taken', 'wp_courseware') . '</span>'; } } // #### Show the cumulative quiz results. $data['quiz_cumulative'] = '-'; if ($quizScoresSoFar_count > 0) { $data['quiz_cumulative'] = '<span class="wpcw_grade_valid">' . number_format($quizScoresSoFar / $quizScoresSoFar_count, 1) . '%</span>'; } } // ####ÊUser Progress $data['course_progress'] = WPCW_stats_convertPercentageToBar($singleUser->course_progress); // #### Grade Sent? $data['grade_sent'] = 'sent' == $singleUser->course_final_grade_sent ? __('Yes', 'wp_courseware') : '-'; // #### Certificate - Show if there's a certificate that can be downloaded. if ($usingCertificates && ($certDetails = WPCW_certificate_getCertificateDetails($singleUser->ID, $courseDetails->course_id, false))) { $data['certificate_available'] = sprintf('<a href="%s" title="%s">%s</a>', WPCW_certificate_generateLink($certDetails->cert_access_key), __('Download the certificate for this user.', 'wp_courseware'), __('Yes', 'wp_courseware')); } else { $data['certificate_available'] = '-'; } // Odd/Even row colouring. $odd = !$odd; $tbl->addRow($data, $odd ? 'alternate' : ''); } // single user } // Check we have some users. // Here are the action buttons for Gradebook. printf('<div class="wpcw_button_group">'); // Button to generate a CSV of the gradebook. printf('<a href="%s" class="button-primary">%s</a> ', admin_url('?wpcw_export=gradebook_csv&course_id=' . $courseDetails->course_id), __('Export Gradebook (CSV)', 'wp_courseware')); printf('<a href="%s" class="button-primary">%s</a> ', admin_url('admin.php?page=WPCW_showPage_GradeBook&action=email_grades&filter=all&course_id=' . $courseDetails->course_id), __('Email Final Grades', 'wp_courseware')); // URL that shows the eligible users who are next to get the email for the final grade. $eligibleURL = sprintf(admin_url('admin.php?page=WPCW_showPage_GradeBook&course_id=%d&filter=eligible_for_final_grade'), $courseDetails->course_id); // Create information about how people are chosen to send grades to. printf('<div id="wpcw_button_group_info_gradebook" class="wpcw_button_group_info">%s</div>', sprintf(__('Grades will only be emailed to students who have <b>completed the course</b> and who have <b>not yet received</b> their final grade. You can see the students who are <a href="%s">eligible to receive the final grade email</a> here.', 'wp_courseware'), $eligibleURL)); printf('</div>'); echo $paging; // Show the filtering to selectively show different quizzes // Filter list can be modified to indicate Group's name instead of 'all' $filters_list = array('all' => sprintf(__('All (%d)', 'wp_courseware'), $userCount_all), 'completed' => sprintf(__('Completed (%d)', 'wp_courseware'), $userCount_completed), 'eligible_for_final_grade' => sprintf(__('Eligible for Final Grade Email (%d)', 'wp_courseware'), $userCount_needGrade), 'to_mark' => sprintf(__('Just Quizzes that Need Marking (%d)', 'wp_courseware'), $userCount_toMark)); // Allow the filters to be customised $filters_list = apply_filters("wpcw_back_filters_gradebook_filters", $filters_list, $courseDetails->course_id); echo WPCW_table_showFilters($filters_list, WPCW_urls_getURLWithParams($summaryPageURL, 'filter') . "&filter=", $currentFilter); // Finally show table echo $tbl->toString(); echo $paging; $page->showPageFooter(); }
/** * Function that show a summary of the quizzes. */ function WPCW_showPage_QuizSummary_load() { global $wpcwdb, $wpdb; $wpdb->show_errors(); // Get the requested page number $paging_pageWanted = WPCW_arrays_getValue($_GET, 'pagenum') + 0; if ($paging_pageWanted == 0) { $paging_pageWanted = 1; } // Title for page with page number $titlePage = false; if ($paging_pageWanted > 1) { $titlePage = sprintf(' - %s %s', __('Page', 'wp_courseware'), $paging_pageWanted); } $page = new PageBuilder(false); $page->showPageHeader(__('Quiz & Survey Summary', 'wp_courseware') . $titlePage, '75%', WPCW_icon_getPageIconURL()); // Handle the quiz deletion before showing remaining quizzes... WPCW_quizzes_handleQuizDeletion($page); // Handle the sorting and filtering $orderBy = WPCW_arrays_getValue($_GET, 'orderby'); $ordering = WPCW_arrays_getValue($_GET, 'order'); // Validate ordering switch ($orderBy) { case 'quiz_title': case 'quiz_id': break; default: $orderBy = 'quiz_id'; 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 = 'desc'; $ordering_opposite = 'asc'; break; } // Was a search string specified? Or a specific item? $searchString = WPCW_arrays_getValue($_GET, 's'); // Create WHERE string based search - Title or Description of Quiz $stringWHERE = false; if ($searchString) { $stringWHERE = $wpdb->prepare(" WHERE quiz_title LIKE %s OR quiz_desc LIKE %s ", '%' . $searchString . '%', '%' . $searchString . '%'); } $summaryPageURL = admin_url('admin.php?page=WPCW_showPage_QuizSummary'); // Show the form for searching ?> <form id="wpcw_quizzes_search_box" method="get" action="<?php echo $summaryPageURL; ?> "> <p class="search-box"> <label class="screen-reader-text" for="wpcw_quizzes_search_input"><?php _e('Search Quizzes', 'wp_courseware'); ?> </label> <input id="wpcw_quizzes_search_input" type="text" value="<?php echo $searchString; ?> " name="s"/> <input class="button" type="submit" value="<?php _e('Search Quizzes', 'wp_courseware'); ?> "/> <input type="hidden" name="page" value="WPCW_showPage_QuizSummary" /> </p> </form> <br/><br/> <?php $SQL_PAGING = "\n\t\t\tSELECT COUNT(*) as quiz_count \n\t\t\tFROM {$wpcwdb->quiz}\t\t\t\n\t\t\t{$stringWHERE}\n\t\t\tORDER BY quiz_id DESC \n\t\t"; $paging_resultsPerPage = 50; $paging_totalCount = $wpdb->get_var($SQL_PAGING); $paging_recordStart = ($paging_pageWanted - 1) * $paging_resultsPerPage + 1; $paging_recordEnd = $paging_pageWanted * $paging_resultsPerPage; $paging_pageCount = ceil($paging_totalCount / $paging_resultsPerPage); $paging_sqlStart = $paging_recordStart - 1; // Show search message - that a search has been tried. if ($searchString) { printf('<div class="wpcw_search_count">%s "%s" (%s %s) (<a href="%s">%s</a>)</div>', __('Search results for', 'wp_courseware'), htmlentities($searchString), $paging_totalCount, _n('result', 'results', $paging_totalCount, 'wp_courseware'), $summaryPageURL, __('reset', 'wp_courseware')); } // Do main query $SQL = "SELECT * \n\t\t\tFROM {$wpcwdb->quiz}\t\t\t\n\t\t\t{$stringWHERE}\n\t\t\tORDER BY {$orderBy} {$ordering}\n\t\t\tLIMIT {$paging_sqlStart}, {$paging_resultsPerPage}\t\t\t \n\t\t\t"; // These are already checked, so they are safe, hence no prepare() // Generate paging code $baseURL = WPCW_urls_getURLWithParams($summaryPageURL, 'pagenum') . "&pagenum="; $paging = WPCW_tables_showPagination($baseURL, $paging_pageWanted, $paging_pageCount, $paging_totalCount, $paging_recordStart, $paging_recordEnd); $quizzes = $wpdb->get_results($SQL); if ($quizzes) { $tbl = new TableBuilder(); $tbl->attributes = array('id' => 'wpcw_tbl_quiz_summary', 'class' => 'widefat wpcw_tbl'); // ID - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=quiz_id"><span>%s</span><span class="sorting-indicator"></span></a>', $baseURL, 'quiz_id' == $orderBy ? $ordering_opposite : 'asc', __('ID', 'wp_courseware')); // ID - render $tblCol = new TableColumn($sortableLink, 'quiz_id'); $tblCol->headerClass = 'quiz_id' == $orderBy ? 'sorted ' . $ordering : 'sortable'; $tblCol->cellClass = "quiz_id"; $tbl->addColumn($tblCol); // Title - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=quiz_title"><span>%s</span><span class="sorting-indicator"></span></a>', $baseURL, 'quiz_title' == $orderBy ? $ordering_opposite : 'asc', __('Quiz Title', 'wp_courseware')); // Title - render $tblCol = new TableColumn($sortableLink, 'quiz_title'); $tblCol->headerClass = 'quiz_title' == $orderBy ? 'sorted ' . $ordering : 'sortable'; $tblCol->cellClass = "quiz_title"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Associated Unit', 'wp_courseware'), 'associated_unit'); $tblCol->cellClass = "associated_unit"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Quiz Type', 'wp_courseware'), 'quiz_type'); $tblCol->cellClass = "quiz_type"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Show Answers', 'wp_courseware'), 'quiz_show_answers'); $tblCol->cellClass = "quiz_type wpcw_center"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Paging', 'wp_courseware'), 'quiz_use_paging'); $tblCol->cellClass = "quiz_type wpcw_center"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Questions', 'wp_courseware'), 'total_questions'); $tblCol->cellClass = "total_questions wpcw_center"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Actions', 'wp_courseware'), 'actions'); $tblCol->cellClass = "actions"; $tbl->addColumn($tblCol); // Stores course details in a mini cache to save lots of MySQL lookups. $miniCourseDetailCache = array(); // Format row data and show it. $odd = false; foreach ($quizzes as $quiz) { $data = array(); // URLs $editURL = admin_url('admin.php?page=WPCW_showPage_ModifyQuiz&quiz_id=' . $quiz->quiz_id); $surveyExportURL = admin_url('admin.php?page=WPCW_showPage_QuizSummary&wpcw_export=csv_export_survey_data&quiz_id=' . $quiz->quiz_id); // Maintain paging where possible. $deleteURL = $baseURL . '&action=delete&quiz_id=' . $quiz->quiz_id; // Basic Details $data['quiz_id'] = $quiz->quiz_id; // Quiz Title $data['quiz_title'] = sprintf('<b><a href="%s">%s</a></b>', $editURL, $quiz->quiz_title); if ($quiz->quiz_desc) { $data['quiz_title'] .= '<span class="wpcw_quiz_desc">' . $quiz->quiz_desc . '</span>'; } // Associated Unit if ($quiz->parent_unit_id > 0 && ($unitDetails = get_post($quiz->parent_unit_id))) { $data['associated_unit'] = sprintf('<span class="associated_unit_unit"><b>%s</b>: <a href="%s" target="_blank" title="%s \'%s\'...">%s</a></span>', __('Unit', 'wp_courseware'), get_permalink($unitDetails->ID), __('View ', 'wp_courseware'), $unitDetails->post_title, $unitDetails->post_title); // Also add associated course if (isset($miniCourseDetailCache[$quiz->parent_course_id])) { $courseDetails = $miniCourseDetailCache[$quiz->parent_course_id]; } else { // Save course details to cache (as likely to use it again). $courseDetails = $miniCourseDetailCache[$quiz->parent_course_id] = WPCW_courses_getCourseDetails($quiz->parent_course_id); } // Might not have course details. if ($courseDetails) { $data['associated_unit'] .= sprintf('<span class="associated_unit_course"><b>%s:</b> <a href="admin.php?page=WPCW_showPage_ModifyCourse&course_id=%d" title="%s \'%s\'...">%s</a></span>', __('Course', 'wp_courseware'), $courseDetails->course_id, __('Edit ', 'wp_courseware'), $courseDetails->course_title, $courseDetails->course_title); } } else { $data['associated_unit'] = 'n/a'; } // Showing Answers or paging? $data['quiz_show_answers'] = 'show_answers' == $quiz->quiz_show_answers ? '<span class="wpcw_tick"></span>' : '-'; $data['quiz_use_paging'] = 'use_paging' == $quiz->quiz_paginate_questions ? '<span class="wpcw_tick"></span>' : '-'; // Type of quiz $data['quiz_type'] = WPCW_quizzes_getQuizTypeName($quiz->quiz_type); // Show passmark for blocking quizzes. if ('quiz_block' == $quiz->quiz_type) { $data['quiz_type'] .= '<span class="wpcw_quiz_pass_info">' . sprintf(__('Min. Pass Mark of %d%%', 'wp_courseware'), $quiz->quiz_pass_mark) . '</span>'; } // Total number of questions $data['total_questions'] = WPCW_quizzes_calculateActualQuestionCount($quiz->quiz_id); // Actions $data['actions'] = '<ul class="wpcw_action_link_list">'; $data['actions'] .= sprintf('<li><a href="%s" class="button-primary">%s</a></li>', $editURL, __('Edit', 'wp_courseware')); $data['actions'] .= sprintf('<li><a href="%s" class="button-secondary wpcw_action_link_delete_quiz wpcw_action_link_delete" rel="%s">%s</a></li>', $deleteURL, __('Are you sure you wish to delete this quiz?', 'wp_courseware'), __('Delete', 'wp_courseware')); // Add export button for surveys if ('survey' == $quiz->quiz_type) { $data['actions'] .= sprintf('<li class="wpcw_action_item_newline"><a href="%s" class="button-secondary">%s</a></li>', $surveyExportURL, __('Export Responses', 'wp_courseware')); } $data['actions'] .= '</ul>'; // Odd/Even row colouring. $odd = !$odd; $tbl->addRow($data, $odd ? 'alternate' : ''); } // Finally show table echo $paging; echo $tbl->toString(); echo $paging; } else { printf('<p>%s</p>', __('There are currently no quizzes to show. Why not create one?', 'wp_courseware')); } $page->showPageFooter(); }
/** * Function to show a list of questions in the question pool for use by a standard page or the AJAX thickbox. * * @param Integer $itemsPerPage The number of items to show on each table page. * @param Array $paramSrc The array of parameters to use for filtering/searching the question pool. * @param String $actionMode The type of mode we're in (ajax or std). * @param PageBuilder $page The current page object (optional). */ function WPCW_questionPool_showPoolTable($itemsPerPage, $paramSrc, $actionMode = 'std', $page = false) { global $wpcwdb, $wpdb; $wpdb->show_errors(); // AJAX loader if ('ajax' == $actionMode) { printf('<img src="%simg/ajax_loader.gif" class="wpcw_loader" style="display: none;" />', WPCW_plugin_getPluginPath()); } // Check to see if we've got questions to process if ('std' == $actionMode) { WPCW_showPage_QuestionPool_processActionForm($page); } $paging_pageWanted = WPCW_arrays_getValue($paramSrc, 'pagenum') + 0; if ($paging_pageWanted == 0) { $paging_pageWanted = 1; } // Handle the sorting and filtering $orderBy = WPCW_arrays_getValue($paramSrc, 'orderby'); $ordering = WPCW_arrays_getValue($paramSrc, 'order'); // Validate ordering switch ($orderBy) { case 'question_question': case 'question_type': break; // Default and question_id //case 'question_id': // Default and question_id //case 'question_id': default: $orderBy = 'qs.question_id'; 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 = 'desc'; $ordering_opposite = 'asc'; break; } // Was a search string specified? Or a specific item? $searchString = WPCW_arrays_getValue($paramSrc, 's'); // Create WHERE string based search - Title or Description of Quiz $SQL_WHERE = false; if ($searchString) { $SQL_WHERE = $wpdb->prepare(" AND question_question LIKE %s", '%' . $searchString . '%'); } $summaryPageURL = admin_url('admin.php?page=WPCW_showPage_QuestionPool'); // Show the form for searching ?> <form id="wpcw_questions_search_box" method="get" action="<?php echo $summaryPageURL; ?> "> <p class="search-box"> <label class="screen-reader-text" for="wpcw_questions_search_input"><?php _e('Search Questions', 'wp_courseware'); ?> </label> <input id="wpcw_questions_search_input" type="text" value="<?php echo $searchString; ?> " name="s"/> <input class="button" type="submit" value="<?php _e('Search Questions', 'wp_courseware'); ?> "/> <input type="hidden" name="page" value="WPCW_showPage_QuestionPool" /> </p> </form> <?php $SQL_TAG_FILTER = false; $tagFilter = intval(WPCW_arrays_getValue($paramSrc, 'filter', false)); // See if we have any tag filtering to do. if ($tagFilter > 0) { // Ensure we add the tag mapping table to the query $SQL_TAG_FILTER = "\n\t\t\tLEFT JOIN {$wpcwdb->question_tag_mapping} qtm ON qtm.question_id = qs.question_id\t\n\t\t"; $SQL_WHERE .= $wpdb->prepare("\n\t\t\tAND qtm.tag_id = %d\n\t\t\tAND qs.question_question IS NOT NULL \n\t\t", $tagFilter); // } $SQL_PAGING = "\n\t\t\tSELECT COUNT(*) as question_count \n\t\t\tFROM {$wpcwdb->quiz_qs} qs\n\t\t\t{$SQL_TAG_FILTER}\n\t\t\tWHERE question_type <> 'random_selection'\n\t\t\t{$SQL_WHERE} \n\t\t"; $paging_resultsPerPage = $itemsPerPage; $paging_totalCount = $wpdb->get_var($SQL_PAGING); $paging_recordStart = ($paging_pageWanted - 1) * $paging_resultsPerPage + 1; $paging_recordEnd = $paging_pageWanted * $paging_resultsPerPage; $paging_pageCount = ceil($paging_totalCount / $paging_resultsPerPage); $paging_sqlStart = $paging_recordStart - 1; // Show search message - that a search has been tried. if ($searchString) { printf('<div class="wpcw_search_count">%s "%s" (%s %s) (<a href="%s">%s</a>)</div>', __('Search results for', 'wp_courseware'), htmlentities($searchString), $paging_totalCount, _n('result', 'results', $paging_totalCount, 'wp_courseware'), $summaryPageURL, __('reset', 'wp_courseware')); } // Do main query $SQL = "SELECT * \n\t\t\tFROM {$wpcwdb->quiz_qs} qs\t\t\t\n\t\t\t{$SQL_TAG_FILTER}\t\t\t\n\t\t\tWHERE question_type <> 'random_selection'\n\t\t\t{$SQL_WHERE}\n\t\t\tORDER BY {$orderBy} {$ordering}\n\t\t\tLIMIT {$paging_sqlStart}, {$paging_resultsPerPage}\t\t\t \n\t\t\t"; // These are already checked, so they are safe, hence no prepare() // Generate paging code $baseURL = WPCW_urls_getURLWithParams($summaryPageURL, 'pagenum') . "&pagenum="; $questions = $wpdb->get_results($SQL); $tbl = new TableBuilder(); $tbl->attributes = array('id' => 'wpcw_tbl_question_pool', 'class' => 'widefat wpcw_tbl'); // Checkbox Col //$tblCol = new TableColumn(false, 'question_selection'); //$tblCol->cellClass = "question_selection wpcw_center"; //$tbl->addColumn($tblCol); // Wanting sorting links... in standard mode if ('std' == $actionMode) { // Checkbox field (no name, as we'll use jQuery to do a check all) $tblCol = new TableColumn('<input type="checkbox" />', 'question_id_cb'); $tblCol->cellClass = "wpcw_center wpcw_select_cb"; $tblCol->headerClass = "wpcw_center wpcw_select_cb"; $tbl->addColumn($tblCol); // ID - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=question_id"><span>%s</span><span class="sorting-indicator"></span></a>', $baseURL, 'question_id' == $orderBy ? $ordering_opposite : 'asc', __('ID', 'wp_courseware')); // ID - render $tblCol = new TableColumn($sortableLink, 'question_id'); $tblCol->headerClass = 'question_id' == $orderBy ? 'sorted ' . $ordering : 'sortable'; $tblCol->cellClass = "question_id"; $tbl->addColumn($tblCol); // Question - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=question_question"><span>%s</span><span class="sorting-indicator"></span></a>', $baseURL, 'question_question' == $orderBy ? $ordering_opposite : 'asc', __('Question', 'wp_courseware')); // Question - render $tblCol = new TableColumn($sortableLink, 'question_question'); $tblCol->headerClass = 'question_question' == $orderBy ? 'sorted ' . $ordering : 'sortable'; $tblCol->cellClass = "question_question"; $tbl->addColumn($tblCol); // Question Type - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=question_type"><span>%s</span><span class="sorting-indicator"></span></a>', $baseURL, 'question_type' == $orderBy ? $ordering_opposite : 'asc', __('Question Type', 'wp_courseware')); // Question Type - render $tblCol = new TableColumn($sortableLink, 'question_type'); $tblCol->headerClass = ('question_type' == $orderBy ? 'sorted ' . $ordering : 'sortable') . ' wpcw_center'; $tblCol->cellClass = "question_type"; $tbl->addColumn($tblCol); } else { $tblCol = new TableColumn(__('ID', 'wp_courseware'), 'question_id'); $tblCol->cellClass = "question_id"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Question', 'wp_courseware'), 'question_question'); $tblCol->cellClass = "question_question"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Question Type', 'wp_courseware'), 'question_type'); $tblCol->cellClass = "question_type"; $tbl->addColumn($tblCol); } $tblCol = new TableColumn(__('Associated Quizzes', 'wp_courseware'), 'associated_quizzes'); $tblCol->headerClass = "wpcw_center"; $tblCol->cellClass = "associated_quizzes wpcw_center"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Tags', 'wp_courseware'), 'question_tags'); $tblCol->cellClass = "question_tags wpcw_center"; $tbl->addColumn($tblCol); // Actions $tblCol = new TableColumn(__('Actions', 'wp_courseware'), 'actions'); $tblCol->cellClass = "actions actions_right"; $tblCol->headerClass = "actions_right"; $tbl->addColumn($tblCol); // Stores course details in a mini cache to save lots of MySQL lookups. $miniCourseDetailCache = array(); // Format row data and show it. if ($questions) { $odd = false; foreach ($questions as $singleQuestion) { $data = array(); // URLs $editURL = admin_url('admin.php?page=WPCW_showPage_ModifyQuestion&question_id=' . $singleQuestion->question_id); // Maintain paging where possible. $deleteURL = $baseURL . '&action=delete&question_id=' . $singleQuestion->question_id; // Basic Details $data['question_id'] = $singleQuestion->question_id; $data['question_type'] = WPCW_quizzes_getQuestionTypeName($singleQuestion->question_type); $data['question_id_cb'] = sprintf('<input type="checkbox" name="question_%d" />', $singleQuestion->question_id); // Association Count $data['associated_quizzes'] = $singleQuestion->question_usage_count; // Actions - Std mode if ('std' == $actionMode) { // Edit by clicking $data['question_question'] = sprintf('<a href="%s">%s</a>', $editURL, $singleQuestion->question_question); $data['actions'] = '<ul class="wpcw_action_link_list">'; $data['actions'] .= sprintf('<li><a href="%s" class="button-primary">%s</a></li>', $editURL, __('Edit', 'wp_courseware')); $data['actions'] .= sprintf('<li><a href="%s" class="button-secondary wpcw_action_link_delete_question wpcw_action_link_delete" rel="%s">%s</a></li>', $deleteURL, __('Are you sure you wish to delete this question? This cannot be undone.', 'wp_courseware'), __('Delete', 'wp_courseware')); $data['actions'] .= '</ul>'; } else { if ('ajax' == $actionMode) { // No Edit by clicking $data['question_question'] = $singleQuestion->question_question . sprintf('<span class="wpcw_action_status wpcw_action_status_added">%s</span>', __('Added', 'wp_courseware')); $data['actions'] = '<ul class="wpcw_action_link_list">'; $data['actions'] .= sprintf('<li><a href="#" class="button-primary wpcw_tb_action_add" data-questionnum="%d">%s</a></li>', $singleQuestion->question_id, __('Add To Quiz', 'wp_courseware')); $data['actions'] .= '</ul>'; } } // Tags $data['question_tags'] = sprintf('<span class="wpcw_quiz_details_question_tags" data-questionid="%d" id="wpcw_quiz_details_question_tags_%d">', $singleQuestion->question_id, $singleQuestion->question_id); $data['question_tags'] .= WPCW_questions_tags_render($singleQuestion->question_id, WPCW_questions_tags_getTagsForQuestion($singleQuestion->question_id)); $data['question_tags'] .= '</span>'; // Odd/Even row colouring. $odd = !$odd; $tbl->addRow($data, $odd ? 'alternate' : ''); } } else { // No questions - show error in table. $tbl->addRowObj(new RowDataSimple('wpcw_center wpcw_none_found', __('There are currently no questions to show.', 'wp_courseware'), 7)); } // Add the form for the start of the multiple-add $formWrapper_start = false; if ('std' == $actionMode) { // Set the action URL to preserve parameters that we have. $formWrapper_start = sprintf('<form method="POST" action="%s">', WPCW_urls_getURLWithParams($summaryPageURL, 'pagenum')); } // Create tag filter (uses a form) $tagFilter = WPCW_questions_tags_createTagFilter($tagFilter, 'WPCW_showPage_QuestionPool'); // Work out paging and filtering $paging = WPCW_tables_showPagination($baseURL, $paging_pageWanted, $paging_pageCount, $paging_totalCount, $paging_recordStart, $paging_recordEnd, $tagFilter); // Show the actions $formWrapper_end = false; if ('std' == $actionMode) { $formWrapper_end = WPCW_showPage_QuestionPool_actionForm(); // Form tag - needed for processing $formWrapper_end .= '</form>'; } // Finally show table return $paging . $formWrapper_start . $tbl->toString() . $formWrapper_end . $paging; }