/** * Convert page/post to a course unit */ function WPCW_showPage_ConvertPage_load() { $page = new PageBuilder(false); $page->showPageHeader(__('Convert Page/Post to Course Unit', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); // Future Feature - Check user can edit other people's pages - use edit_others_pages or custom capability. if (!current_user_can('manage_options')) { $page->showMessage(__('Sorry, but you are not allowed to edit this page/post.', 'wp_courseware'), true); $page->showPageFooter(); return false; } // Check that post ID is valid $postID = WPCW_arrays_getValue($_GET, 'postid') + 0; $convertPost = get_post($postID); if (!$convertPost) { $page->showMessage(__('Sorry, but the specified page/post does not appear to exist.', 'wp_courseware'), true); $page->showPageFooter(); return false; } // Check that post isn't already a course unit before trying change. // This is where the conversion takes place. if ('course_unit' != $convertPost->post_type) { // Confirm we want to do the conversion if (!isset($_GET['confirm'])) { $message = sprintf(__('Are you sure you wish to convert the <em>%s</em> to a course unit?', 'wp_courseware'), $convertPost->post_type); $message .= '<br/><br/>'; // Yes Button $message .= sprintf('<a href="%s&postid=%d&confirm=yes" class="button-primary">%s</a>', admin_url('admin.php?page=WPCW_showPage_ConvertPage'), $postID, __('Yes, convert it', 'wp_courseware')); // Cancel $message .= sprintf(' <a href="%s&postid=%d&confirm=no" class="button-secondary">%s</a>', admin_url('admin.php?page=WPCW_showPage_ConvertPage'), $postID, __('No, don\'t convert it', 'wp_courseware')); $page->showMessage($message); $page->showPageFooter(); return false; } else { // Confirmed conversion if ($_GET['confirm'] == 'yes') { $postDetails = array(); $postDetails['ID'] = $postID; $postDetails['post_type'] = 'course_unit'; // Update the post into the database wp_update_post($postDetails); } // Cancelled conversion if ($_GET['confirm'] != 'yes') { $page->showMessage(__('Conversion to a course unit cancelled.', 'wp_courseware'), false); $page->showPageFooter(); return false; } } } // Check conversion happened $convertedPost = get_post($postID); if ('course_unit' == $convertedPost->post_type) { $page->showMessage(sprintf(__('The page/post was successfully converted to a course unit. You can <a href="%s">now edit the course unit</a>.', 'wp_courseware'), admin_url(sprintf('post.php?post=%d&action=edit', $postID)))); } else { $page->showMessage(__('Unfortunately, there was an error trying to convert the page/post to a course unit. Perhaps you could try again?', 'wp_courseware'), true); } $page->showPageFooter(); }
/** * Function that allows a quiz to be created or edited. */ function WPCW_showPage_ModifyQuiz_load() { // Thickbox needed for random and quiz windows. add_thickbox(); $page = new PageBuilder(true); $quizDetails = false; $adding = false; $quizID = false; // Check POST and GET if (isset($_GET['quiz_id'])) { $quizID = $_GET['quiz_id'] + 0; } else { if (isset($_POST['quiz_id'])) { $quizID = $_POST['quiz_id'] + 0; } } // Trying to edit a quiz if ($quizDetails = WPCW_quizzes_getQuizDetails($quizID, false, false, false)) { // Abort if quiz not found. if (!$quizDetails) { $page->showPageHeader(__('Edit Quiz/Survey', 'wp_courseware'), '70%', WPCW_icon_getPageIconURL()); $page->showMessage(__('Sorry, but that quiz/survey could not be found.', 'wp_courseware'), true); $page->showPageFooter(); return; } else { // Start form prolog - with quiz ID printf('<form method="POST" action="%s&quiz_id=%d" name="wpcw_quiz_details_modify" id="wpcw_quiz_details_modify">', admin_url('admin.php?page=WPCW_showPage_ModifyQuiz'), $quizDetails->quiz_id); $page->showPageHeader(__('Edit Quiz/Survey', 'wp_courseware'), '70%', WPCW_icon_getPageIconURL()); } } else { // Start form prolog - no quiz ID printf('<form method="POST" action="%s" name="wpcw_quiz_details_modify" id="wpcw_quiz_details_modify">', admin_url('admin.php?page=WPCW_showPage_ModifyQuiz')); $page->showPageHeader(__('Add Quiz/Survey', 'wp_courseware'), '70%', WPCW_icon_getPageIconURL()); $adding = true; } // Generate the tabs. $tabList = array('wpcw_section_break_quiz_general' => array('label' => __('General Settings', 'wp_courseware')), 'wpcw_section_break_quiz_logic' => array('label' => __('Quiz Behaviour Settings', 'wp_courseware')), 'wpcw_section_break_quiz_results' => array('label' => __('Result Settings', 'wp_courseware')), 'wpcw_section_break_quiz_custom_feedback' => array('label' => __('Custom Feedback', 'wp_courseware'), 'cssclass' => 'wpcw_quiz_only_tab'), 'wpcw_section_break_quiz_questions' => array('label' => __('Manage Questions', 'wp_courseware'))); global $wpcwdb; $formDetails = array('wpcw_section_break_quiz_general' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab(false)), 'quiz_title' => array('label' => __('Quiz Title', 'wp_courseware'), 'type' => 'text', 'required' => true, 'cssclass' => 'wpcw_quiz_title', 'desc' => __('The title of your quiz or survey. Your trainees will be able to see this quiz title.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 150, 'minlen' => 1, 'regexp' => '/^[^<>]+$/', 'error' => __('Please specify a name for your quiz or survey, up to a maximum of 150 characters, just no angled brackets (< or >).', 'wp_courseware'))), 'quiz_desc' => array('label' => __('Quiz/Survey Description', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'cssclass' => 'wpcw_quiz_desc', 'rows' => 2, 'desc' => __('(Optional) The description of this quiz. Your trainees won\'t see this description. It\'s just for your reference.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 5000, 'minlen' => 1, 'error' => __('Please limit the description of your quiz to 5000 characters.', 'wp_courseware'))), 'quiz_type' => array('label' => __('Quiz Type', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_quiz_type wpcw_quiz_type_hide_pass', 'data' => array('survey' => __('<b>Survey Mode</b> - No correct answers, just collect information.', 'wp_courseware'), 'quiz_block' => __('<b>Quiz Mode - Blocking</b> - require trainee to correctly answer questions before proceeding. Trainee must achieve <b>minimum pass mark</b> to progress to the next unit.', 'wp_courseware'), 'quiz_noblock' => __('<b>Quiz Mode - Non-blocking</b> - require trainee to answer a number of questions before proceeding, but allow them to progress to the next unit <b>regardless of their pass mark</b>.', 'wp_courseware'))), 'wpcw_section_break_quiz_logic' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab(false)), 'quiz_pass_mark' => array('label' => __('Pass Mark', 'wp_courseware'), 'type' => 'select', 'required' => true, 'cssclass' => 'wpcw_quiz_block_only wpcw_quiz_only', 'data' => WPCW_quizzes_getPercentageList(__('-- Select a pass mark --', 'wp_courseware')), 'desc' => __('The minimum pass mark that your trainees need to achieve to progress on to the next unit.', 'wp_courseware')), 'quiz_attempts_allowed' => array('label' => __('Number of Attempts Allowed?', 'wp_courseware'), 'type' => 'select', 'required' => true, 'cssclass' => 'wpcw_quiz_block_only wpcw_quiz_only', 'data' => WPCW_quizzes_getAttemptList(), 'desc' => __('The maximum number of attempts that a trainee is given to complete a quiz for blocking quizzes.', 'wp_courseware')), 'quiz_show_survey_responses' => array('label' => __('Show Survey Responses?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_survey_only', 'data' => array('show_responses' => __('<b>Show Responses</b> - Show the trainee their survey responses.', 'wp_courseware'), 'no_responses' => __('<b>No Responses</b> - Don\'t show the trainee their survey responses.', 'wp_courseware')), 'desc' => __('This setting allows you to choose whether or not you want students to be able to review their past survey responses when they return to units.', 'wp_courseware')), 'quiz_paginate_questions' => array('label' => __('Paginate Questions?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_quiz_paginate_questions', 'data' => array('use_paging' => __('<b>Use Paging</b> - This setting will display quiz questions one at a time allowing students to progress through questions individually within a frame in your unit page.', 'wp_courseware'), 'no_paging' => __('<b>No Paging</b> - Don\'t use any paging. Show all quiz questions at once on the unit page.', 'wp_courseware')), 'suffix_subitems' => array('use_paging' => array('quiz_paginate_questions_settings' => array('type' => 'checkboxlist', 'required' => false, 'cssclass' => 'wpcw_quiz_paginate_questions_group', 'data' => array('allow_review_before_submission' => '<b>' . __('Allow Review Before Final Submission', 'wp_courseware') . '</b> - ' . __('If selected, students will be presented with an opportunity to review an editable list of all answers before final submission.', 'wp_courseware'), 'allow_students_to_answer_later' => '<b>' . __('Allow Students to Answer Later', 'wp_courseware') . '</b> - ' . __('If selected, the student will be able to click the "Answer Later" button and progress to the next question without answering. The question will be presented again at the end of the quiz.', 'wp_courseware'), 'allow_nav_previous_questions' => '<b>' . __('Allow Navigation to Previous Questions', 'wp_courseware') . '</b> - ' . __('If selected, a "Previous Question" button will be displayed, allowing students to freely navigate backwards and forwards through questions.', 'wp_courseware')))))), 'quiz_timer_mode' => array('label' => __('Set Time Limit for Quiz?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_quiz_timer_mode wpcw_quiz_block_only', 'data' => array('use_timer' => __('<b>Specify a Quiz Time Limit</b> - Give the trainee a fixed amount of time to complete the quiz.', 'wp_courseware'), 'no_timer' => __('<b>No Time Limit</b> - the trainee can take as long as they wish to complete the quiz.', 'wp_courseware'))), 'quiz_timer_mode_limit' => array('label' => __('Time Limit (in minutes)', 'wp_courseware'), 'type' => 'text', 'required' => false, 'cssclass' => 'wpcw_quiz_timer_mode_limit wpcw_quiz_timer_mode_active_only wpcw_quiz_block_only', 'extrahtml' => __('Minutes', 'wp_courseware'), 'validate' => array('type' => 'number', 'max' => 1000, 'min' => 1, 'error' => 'Please choose time limit between 1 and 1000 minutes.')), 'wpcw_section_break_quiz_results' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab(false)), 'quiz_show_answers' => array('label' => __('Show Answers?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_quiz_show_answers wpcw_quiz_only', 'data' => array('show_answers' => __('<b>Show Answers</b> - Show the trainee the correct answers before they progress.', 'wp_courseware'), 'no_answers' => __('<b>No Answers</b> - Don\'t show the trainee any answers before they progress.', 'wp_courseware')), 'extrahtml' => '<div class="wpcw_msg_info wpcw_msg wpcw_msg_in_form wpcw_msg_error_no_answers_selected" style="display: none">' . __('If this option is selected, students will not be able to view correct or incorrect answers.', 'wp_courseware') . '</div>', 'suffix_subitems' => array('show_answers' => array('show_answers_settings' => array('type' => 'checkboxlist', 'required' => false, 'cssclass' => '', 'errormsg' => __('Please choose at least one option when showing correct answers.', 'wp_courseware'), 'data' => array('show_correct_answer' => '<b>' . __('Show correct answer', 'wp_courseware') . '</b> - ' . __('Show the trainee the correct answers before they progress.', 'wp_courseware'), 'show_user_answer' => '<b>' . __('Show user\'s answer', 'wp_courseware') . '</b> - ' . __('Show the trainee the answer they submitted before they progress.', 'wp_courseware'), 'show_explanation' => '<b>' . __('Show explanation', 'wp_courseware') . '</b> - ' . __('Show the trainee an explanation for the correct answer (if there is one).', 'wp_courseware'), 'mark_answers' => '<b>' . __('Mark Answers', 'wp_courseware') . '</b> - ' . __('This option will show correct answers with a green check mark, and incorrect answers with a red "X".', 'wp_courseware'), 'show_results_later' => '<b>' . __('Leave quiz results available for later viewing?', 'wp_courseware') . '</b> - ' . __('This setting allows you to choose whether or not you want students to be able to review their past quiz answers when they return to units.', 'wp_courseware')), 'extrahtml' => '<div class="wpcw_msg_error wpcw_msg wpcw_msg_in_form wpcw_msg_error_show_answers_none_selected" style="display: none">' . __('To make use of this showing answers setting, at least one of the above settings should be ticked. Otherwise, no answers are actually shown.', 'wp_courseware') . '</div>')))), 'quiz_results_by_tag' => array('label' => __('Show Results by Tag?', 'wp_courseware'), 'type' => 'checkbox', 'required' => false, 'extralabel' => __('<b>Display results by question tag</b> - In addition to the overall score, indicate a breakdown of the results for each question tag.', 'wp_courseware')), 'quiz_results_by_timer' => array('label' => __('Show Completion Time?', 'wp_courseware'), 'type' => 'checkbox', 'required' => false, 'cssclass' => 'wpcw_quiz_timer_mode_active_only wpcw_quiz_block_only', 'extralabel' => __('<b>Display completion time for timed quiz</b> - If the quiz has been timed, this option will display the student\'s total time used for completing the quiz.', 'wp_courseware'))); $form = new RecordsForm($formDetails, $wpcwdb->quiz, 'quiz_id', false, 'wpcw_quiz_details_modify'); $form->customFormErrorMsg = __('Sorry, but unfortunately there were some errors saving the quiz details. Please fix the errors and try again.', 'wp_courseware'); $form->setAllTranslationStrings(WPCW_forms_getTranslationStrings()); // Got to summary of quizzes $directionMsg = '<br/></br>' . sprintf(__('Do you want to return to the <a href="%s">quiz summary page</a>?', 'wp_courseware'), admin_url('admin.php?page=WPCW_showPage_QuizSummary')); // Override success messages $form->msg_record_created = __('Quiz details successfully created.', 'wp_courseware') . $directionMsg; $form->msg_record_updated = __('Quiz details successfully updated.', 'wp_courseware') . $directionMsg; $form->setPrimaryKeyValue($quizID); $form->setSaveButtonLabel(__('Save All Quiz Settings & Questions', 'wp_courseware')); // Do default checking based on quiz type. $form->filterBeforeSaveFunction = 'WPCW_actions_quizzes_beforeQuizSaved'; $form->afterSaveFunction = 'WPCW_actions_quizzes_afterQuizSaved'; // Set defaults when creating a new one if ($adding) { $form->loadDefaults(array('quiz_pass_mark' => 50, 'quiz_type' => 'quiz_noblock', 'quiz_show_survey_responses' => 'no_responses', 'quiz_show_answers' => 'show_answers', 'show_answers_settings' => array('show_correct_answer' => 'on', 'show_user_answer' => 'on', 'show_explanation' => 'on', 'mark_answers' => 'on', 'show_results_later' => 'on'), 'quiz_paginate_questions' => 'no_paging', 'quiz_paginate_questions_settings' => array('allow_review_before_submission' => 'on', 'allow_students_to_answer_later' => 'on', 'allow_nav_previous_questions' => 'on'), 'quiz_timer_mode' => 'no_timer', 'quiz_timer_mode_limit' => '15', 'quiz_results_by_tag' => 'on', 'quiz_results_by_timer' => 'on')); } // Get the rendered form, extract the start and finish form tags so that // we can use the form across multiple panes, and submit other data such // as questions along with the quiz itself. We're doing this because the RecordsForm // object actually does a really good job, so we don't want to refactor to remove it. $formHTML = $form->getHTML(); $formHTML = preg_replace('/^(\\s*?)(<form(.*?>))/', '', $formHTML); $formHTML = preg_replace('/<\\/form>(\\s*?)$/', '', $formHTML); // Need to move the submit button to before the closing form tag to allow it // to render on the page as expected after the questions drag-n-drop section. // Don't bother if we're not showing any questions yet though. $buttonHTML = false; if ($form->primaryKeyValue > 0) { $pattern = '/<p class="submit">(\\C*?)<\\/p>/'; if (preg_match($pattern, $formHTML, $matches)) { // Found it, so add to variable to show later, and strip // it from the HTML so far. $buttonHTML = $matches[0]; $formHTML = str_replace($buttonHTML, false, $formHTML); } } // Not got any questions to show yet, so hide questions tab. if ($form->primaryKeyValue <= 0) { unset($tabList['wpcw_section_break_quiz_questions']); unset($tabList['wpcw_section_break_quiz_custom_feedback']); } // Show a placeholder for an error message that may occur within tabs. printf('<div class="wpcw_msg wpcw_msg_error wpcw_section_error_within_tabs">%s</div>', __('Unfortunately, there are a few missing details that need to be added before this quiz can be saved. Please resolve them and try again.', 'wp_courseware')); // Render the tabs echo WPCW_tabs_generateTabHeader($tabList, 'wpcw_quizzes_tabs'); // The main quiz settings echo $formHTML; // Try to see if we've got an ID having saved the form from a first add // or we're editing the form if ($form->primaryKeyValue > 0) { $quizID = $form->primaryKeyValue; // Top for jumps. printf('<a name="top"></a>'); // ### 1) Custom Feedback Messages printf('<div class="wpcw_form_break_tab"></div>'); printf('<div class="form-table" id="wpcw_section_break_quiz_custom_feedback">'); WPCW_showPage_customFeedback_showEditForms($quizID, $page); printf('</div>'); // ### 2) Question Settings printf('<div class="wpcw_form_break_tab"></div>'); printf('<div class="form-table" id="wpcw_section_break_quiz_questions">'); WPCW_showPage_ModifyQuiz_showQuestionEntryForms($quizID, $page); printf('</div>'); } // Reshow the button here echo $buttonHTML; // The closing form tag echo '</form>'; // .wpcw_tab_wrapper echo '</div>'; // The thickboxes for the page WPCW_showPage_thickbox_questionPool(); WPCW_showPage_thickbox_randomQuestion(); $page->showPageFooter(); }
/** * Show the export course page. */ function WPCW_showPage_ImportExport_export() { $page = new PageBuilder(true); $page->showPageHeader(__('Export Training Course', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); // Show form of courses that can be exported. $form = new FormBuilder('wpcw_export'); $form->setSubmitLabel(__('Export Course', 'wp_courseware')); // Course selection $formElem = new FormElement('export_course_id', __('Course to Export', 'wp_courseware'), true); $formElem->setTypeAsComboBox(WPCW_courses_getCourseList(__('--- Select a course to export ---', 'wp_courseware'))); $form->addFormElement($formElem); // Options for what to export $formElem = new FormElement('what_to_export', __('What to Export', 'wp_courseware'), true); $formElem->setTypeAsRadioButtons(array('whole_course' => __('<b>All</b> - The whole course - including modules, units and quizzes.', 'wp_courseware'), 'just_course' => __('<b>Just the Course</b> - Just the course title, description and settings (no modules, units or quizzes).', 'wp_courseware'), 'course_modules' => __('<b>Course and Modules</b> - Just the course settings and module settings (no units or quizzes).', 'wp_courseware'), 'course_modules_and_units' => __('<b>Course, Modules and Units</b> - The course settings and module settings and units (no quizzes).', 'wp_courseware'))); $form->addFormElement($formElem); $form->setDefaultValues(array('what_to_export' => 'whole_course')); if ($form->formSubmitted()) { // Do the full export if ($form->formValid()) { // If data is valid, export will be handled by export class. } else { $page->showListOfErrors($form->getListOfErrors(), __('Sorry, but unfortunately there were some errors. Please fix the errors and try again.', 'wp_courseware')); } } // Show selection menu for import/export to save pages WPCW_showPage_ImportExport_menu('export'); printf('<p class="wpcw_doc_quick">'); _e('When you export a course, you\'ll get an <b>XML file</b>, which you can then <b>import into another WordPress website</b> that\'s running <b>WP Courseware</b>.<br/> When you export the course units with a course, just the <b>HTML to render images and video</b> will be copied, but the <b>actual images and video files will not be exported</b>.', 'wp_courseware'); printf('</p>'); echo $form->toString(); $page->showPageFooter(); }
/** * 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(); }
/** * 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(); }
/** * 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); } }
/** * Function that allows a question to be edited. */ function WPCW_showPage_ModifyQuestion_load() { $page = new PageBuilder(true); $page->showPageHeader(__('Edit Single Question', 'wp_courseware'), '70%', WPCW_icon_getPageIconURL()); $questionID = false; // Check POST and GET if (isset($_GET['question_id'])) { $questionID = $_GET['question_id'] + 0; } else { if (isset($_POST['question_id'])) { $questionID = $_POST['question_id'] + 0; } } // Trying to edit a question $questionDetails = WPCW_questions_getQuestionDetails($questionID, true); // Abort if question not found. if (!$questionDetails) { $page->showMessage(__('Sorry, but that question could not be found.', 'wp_courseware'), true); $page->showPageFooter(); return; } // See if the question has been submitted for saving. if ('true' == WPCW_arrays_getValue($_POST, 'question_save_mode')) { WPCW_handler_questions_processSave(false, true); $page->showMessage(__('Question successfully updated.', 'wp_courseware')); // Assume save has happened, so reload the settings. $questionDetails = WPCW_questions_getQuestionDetails($questionID, true); } // Manually set the order to zero, as not needed for ordering in this context. $questionDetails->question_order = 0; switch ($questionDetails->question_type) { case 'multi': $quizObj = new WPCW_quiz_MultipleChoice($questionDetails); break; case 'truefalse': $quizObj = new WPCW_quiz_TrueFalse($questionDetails); break; case 'open': $quizObj = new WPCW_quiz_OpenEntry($questionDetails); break; case 'upload': $quizObj = new WPCW_quiz_FileUpload($questionDetails); break; default: die(__('Unknown quiz type: ', 'wp_courseware') . $questionDetails->question_type); break; } $quizObj->showErrors = true; $quizObj->needCorrectAnswers = true; $quizObj->hideDragActions = true; // #wpcw_quiz_details_questions = needed for media uploader // .wpcw_question_holder_static = needed for wrapping the question using existing HTML. printf('<div id="wpcw_quiz_details_questions"><ul class="wpcw_question_holder_static">'); // Create form wrapper, so that we can save this question. printf('<form method="POST" action="%s?page=WPCW_showPage_ModifyQuestion&question_id=%d" />', admin_url('admin.php'), $questionDetails->question_id); // Question hidden fields printf('<input name="question_id" type="hidden" value="%d" />', $questionDetails->question_id); printf('<input name="question_save_mode" type="hidden" value="true" />'); // Show the quiz so that it can be edited. We're re-using the code we have for editing questions, // to save creating any special form edit code. echo $quizObj->editForm_toString(); // Save and return buttons. printf('<div class="wpcw_button_group"><br/>'); printf('<a href="%s?page=WPCW_showPage_QuestionPool" class="button-secondary">%s</a> ', admin_url('admin.php'), __('« Return to Question Pool', 'wp_courseware')); printf('<input type="submit" class="button-primary" value="%s" />', __('Save Question Details', 'wp_courseware')); printf('</div>'); printf('</form>'); printf('</ul></div>'); $page->showPageFooter(); }
/** * Function that shows the settings page. */ function STWWT_showPage_Settings() { /** * Constant: Documentation on how the mouseover bubble works. */ define('STWWT_DESC_MOUSEOVER', ' <p><img src="' . STWWT_plugin_getPluginPath() . 'img/stw_bubble_example.png" class="stwwt_settings_bubble_example"/> The Shrink The Web mouseover bubble shows a thumbnail of the website when hovered over a link on your WordPress website. This gives website visitors a preview of the link before they visit the website you link to.</p> <p>If the "<b>Automatic</b>" is selected below, all external links will show ShrinkTheWeb preview bubbles. Use <code>class="nopopup"</code> to disable popup bubble for a specific link.</p> <p>If the "<b>Manual</b>" method is selected below, then you choose which links get a preview bubble by adding <code>class="stwpopup"</code> to any link where you want to show them.</p> <div class="stwwt_clear"></div> '); /** * Constant: Documentation on how the embedded code works. */ define('STWWT_DESC_EMBEDDED', ' <p>The Shrink The Web embed code shows a thumbnail for any link you wrap in <code>[thumb][/thumb]</code> or <code>[stwthumb][/stwthumb]</code> tags. Any use of these tags is replaced with the thumbnail of the website included in the tags. <a href="admin.php?page=stwwt_documentation#embed">See some examples on the documentation page</a>. '); /** * Constant: Documentation on how the pro features work. */ define('STWWT_DESC_EMBEDDED_PRO', ' <p>The following features <b>require an upgraded account</b>. You can find more details on the <a href="https://www.shrinktheweb.com/auth/order-page" target="_blank">Shrink The Web Upgrade Page</a>.</p> <p>These settings are <b>global</b>, so they apply to <b>all thumbnails</b> on your website. Some of these settings have a per-thumbnail override, so please read <a href="admin.php?page=stwwt_documentation">the documentation</a> on how to apply these settings to specific thumbnails.</p> '); $page = new PageBuilder(true); $page->showPageHeader(__('Shrink The Web - Website Thumbnails - Settings', 'stwwt'), '70%'); $page->openPane('stw_settings_main', 'Thumbnail Settings'); $settingDetails = array('stwwt_break_main' => array('type' => 'break', 'html' => STWWT_forms_createBreakHTML('Account Settings')), 'stwwt_access_id' => array('label' => 'Access Key Id', 'type' => 'text', 'required' => true, 'cssclass' => 'stwwt_access_id', 'desc' => 'Your Shrink The Web <b>access</b> key. You can find this within your <a href="http://www.shrinktheweb.com/auth/stw-lobby" target="_blank">STW Account Details</a>.', 'validate' => array('type' => 'string', 'regexp' => '/^[A-Za-z0-9]{12,20}$/', 'error' => 'Your STW access key should only contain numbers and letters, and it\'s about 15 characters long.')), 'stwwt_secret_id' => array('label' => 'Secret Key Id', 'type' => 'text', 'required' => true, 'cssclass' => 'stwwt_access_id', 'desc' => 'Your Shrink The Web <b>secret</b> key. You can find this within your <a href="http://www.shrinktheweb.com/auth/stw-lobby" target="_blank">STW Account Details</a>.', 'validate' => array('type' => 'string', 'regexp' => '/^[A-Za-z0-9]{5,10}$/', 'error' => 'Your STW access key should only contain numbers and letters, and it\'s about 5 characters long.')), 'stwwt_account_level' => array('label' => 'Your STW Account Level', 'type' => 'custom', 'html' => false, 'desc' => 'If you change any aspects of your Shrink The Web account (such as upgrades), click on the <b>Save All Settings</b> button below to re-load what features you can use.'), 'stwwt_break_embedded' => array('type' => 'break', 'html' => STWWT_forms_createBreakHTML('Screenshot Settings', 'Save ALL Settings') . '<div class="stwwt_description">' . STWWT_DESC_EMBEDDED . '</div>'), 'stwwt_shortcode' => array('label' => 'Shortcode Syntax', 'type' => 'radio', 'data' => array('stwthumb' => '<b>[stwthumb]</b>', 'thumb' => '[thumb]'), 'default' => 'thumb'), 'stwwt_embedded_default_size' => array('label' => 'Default Screenshot Size', 'type' => 'select', 'data' => array('mcr' => 'Micro (75x56)', 'tny' => 'Tiny (90x68)', 'vsm' => 'Very Small (100x75)', 'sm' => 'Small (120x90)', 'lg' => 'Large (200x150)', 'xlg' => 'Extra Large (320x200)'), 'desc' => 'The size of the thumbnail shown by the thumbnail shortcode.', 'default' => 'lg'), 'stwwt_embedded_cache_length' => array('label' => 'Cache Length in Days', 'type' => 'select', 'data' => array('3' => '3 Days', '7' => '7 Days (recommended)', '10' => '10 Days', '14' => '14 Days', '21' => '21 Days', '30' => '30 Days'), 'desc' => 'How long you want to cache the thumbnails for.', 'account_level' => array('basic', 'plus'), 'account_denied_msg' => STWWT_ACCOUNT_UPGRADE, 'default' => 7), 'stwwt_break_embedded_pro' => array('type' => 'break', 'html' => STWWT_forms_createBreakHTML('PRO Feature Settings', 'Save ALL Settings') . '<div class="stwwt_description">' . STWWT_DESC_EMBEDDED_PRO . '</div>'), 'stwwt_embedded_pro_inside' => array('label' => 'Inside Pages Capture', 'type' => 'radio', 'data' => array('enable' => '<b>Enabled</b>', 'disable' => 'Disabled'), 'account_feature' => 'embedded_pro_inside', 'account_denied_msg' => STWWT_FEATURE_UPGRADE, 'default' => 'disable'), 'stwwt_embedded_pro_full_length' => array('label' => 'Full-length Page Captures', 'type' => 'radio', 'data' => array('enable' => '<b>Enabled</b>', 'disable' => 'Disabled'), 'account_feature' => 'embedded_pro_full_length', 'account_denied_msg' => STWWT_FEATURE_UPGRADE, 'default' => 'disable'), 'stwwt_embedded_pro_custom_quality' => array('label' => 'Custom Thumbnail Quality', 'type' => 'select', 'data' => STWWT_getQualityList(), 'desc' => 'If you want to customise the thumbnail image quality, then you can select a quality value between 1% and 100%. A value of <b>1% is the lowest quality</b>, and <b>100% is the best quality</b>.', 'account_feature' => 'embedded_pro_custom_quality', 'account_denied_msg' => STWWT_FEATURE_UPGRADE), 'stwwt_break_bubble' => array('type' => 'break', 'html' => STWWT_forms_createBreakHTML('Mouseover Bubble Settings', 'Save ALL Settings') . '<div class="stwwt_description">' . STWWT_DESC_MOUSEOVER . '</div>'), 'stwwt_bubble_method' => array('label' => 'Preview Bubbles Show Method', 'type' => 'select', 'data' => array('disable' => 'Disabled', 'automatic' => 'Automatic', 'manual' => 'Manual'), 'default' => 'disable'), 'stwwt_bubble_size' => array('label' => 'Preview Bubbles Thumbnail Size', 'type' => 'select', 'data' => array('sm' => 'Small (120x90)', 'lg' => 'Large (200x150)', 'xlg' => 'Extra Large (320x200)'), 'desc' => 'The size of the thumbnail shown in the preview bubble when a website visitor hovers over a link.', 'default' => 'lg')); // Show main settings form $settings = new STWSettingsForm($settingDetails, STWWT_SETTINGS_KEY, 'stwwt_settings'); $settings->setSaveButtonLabel('Save ALL Settings'); $settings->show(); // #### Support section $page->showPageMiddle('27%'); $yes = sprintf('<img src="%simg/icon_%s.png" />', STWWT_plugin_getPluginPath(), 'tick'); $no = sprintf('<img src="%simg/icon_%s.png" />', STWWT_plugin_getPluginPath(), 'cross'); // Feature check $accountSettings = TidySettings_getSettings(STWWT_SETTINGS_KEY_ACCOUNT); if ($accountSettings) { $page->openPane('stw_settings_support', 'Your Account Features'); ?> <table id="stwwt_feature_comp"> <thead> <tr> <th>Feature</th> <th>Your Account</th> </tr> </thead> <tbody> <?php // Now show the features unset($accountSettings['account_type']); // So we can just loop through settings. foreach ($accountSettings as $settingName => $enabled) { switch ($settingName) { case 'embedded_pro_inside': printf('<tr><th>%s</th><td>%s</td></tr>', 'Inside Pages Capture', 1 == $enabled ? $yes : $no); break; case 'embedded_pro_full_length': printf('<tr><th>%s</th><td>%s</td></tr>', 'Full Length Capture', 1 == $enabled ? $yes : $no); break; case 'embedded_pro_custom_size': printf('<tr><th>%s</th><td>%s</td></tr>', 'Custom Sizes', 1 == $enabled ? $yes : $no); break; case 'embedded_pro_custom_quality': printf('<tr><th>%s</th><td>%s</td></tr>', 'Custom Quality', 1 == $enabled ? $yes : $no); break; // Don't show feature // Don't show feature default: break; } } ?> </tbody> </table> <?php $page->closePane(); } // end of your feature list $page->openPane('stw_settings_support', 'Get a STW Account...'); ?> <div id="stwwt_signup"> <a href="http://www.shrinktheweb.com/user/register" target="_blank"> <img src="http://www.shrinktheweb.com/uploads/stw-banners/shrinktheweb-234x60.gif" alt="Website Thumbnail Provider" class="stwwt_settings_banner" width="234" height="60" alt="Register for a free account with Shrink The Web"> </a> <div class="stwwt_settings_banner_text"> <span>Need an account?</span> <a href="http://www.shrinktheweb.com/user/register" target="_blank" class="button-primary">Register for FREE</a> </div> </div> <?php $page->closePane(); // Support $page->openPane('stw_settings_support', 'Help & Support'); ?> <p>If you've got a problem with the plugin, please follow the following steps.</p> <ol> <li>Check the <a href="http://wordpress.org/extend/plugins/shrinktheweb-website-preview-plugin/faq/" target="_blank">Frequently Asked Questions</a> on WordPress.org. Your issue might already be answered or resolved.</li> <li>Check the <a href="http://wordpress.org/tags/shrinktheweb-website-preview-plugin?forum_id=10" target="_blank">plugin support forum</a> on WordPress.org. Someone might have had the same issue, and fixed it already.</li> <li>If you think the problem is a <b>plugin problem</b>, please raise the problem in the <a href="http://wordpress.org/tags/shrinktheweb-website-preview-plugin?forum_id=10" target="_blank">plugin support forum</a> on WordPress.org, including <b>as much detail as possible</b>, including any <b>error messages</b>.</li> <li>If you think the problem is a <b>STW or STW account problem</b>, please raise the problem in the <a href="http://www.shrinktheweb.com/forum" target="_blank">STW support forum</a>, including <b>as much detail as possible</b>, including any <b>error messages</b>.</li> </ol> <br/> <div class="stwwt_title">A word about the plugin authors...</div> <p>This plugin and the <a href="http://www.shrinktheweb.com" target="_blank">Shrink The Web</a> service has been developed and is provided by <a href="http://www.neosys.net/profile.htm" target="_blank">Neosys Consulting, Inc.</a></p> <?php $page->closePane(); $page->showPageFooter(); }
/** * 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(); }
/** * 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 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(); }
/** * Function that allows a course to be created or edited. */ function WPCW_showPage_ModifyCourse_load() { $page = new PageBuilder(true); $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->showPageHeader(__('Edit Course', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); $page->showMessage(__('Sorry, but that course could not be found.', 'wp_courseware'), true); $page->showPageFooter(); return; } else { $page->showPageHeader(__('Edit Course', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); // Check user is allowed to edit this course. $canEditCourse = apply_filters('wpcw_back_permissions_user_can_edit_course', true, get_current_user_id(), $courseDetails); if (!$canEditCourse) { $page->showMessage(apply_filters('wpcw_back_msg_permissions_user_can_edit_course', __('You are currently not permitted to edit this course.', 'wp_courseware'), get_current_user_id(), $courseDetails), true); $page->showPageFooter(); return; } } } else { $page->showPageHeader(__('Add Course', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); // Check user is allowed to add another course. $canAddCourse = apply_filters('wpcw_back_permissions_user_can_add_course', true, get_current_user_id()); if (!$canAddCourse) { $page->showMessage(apply_filters('wpcw_back_msg_permissions_user_can_add_course', __('You are currently not permitted to add a new course.', 'wp_courseware'), get_current_user_id()), true); $page->showPageFooter(); return; } } // We've requested a course tool. Do the checks here... if ($courseDetails && ($action = WPCW_arrays_getValue($_GET, 'action'))) { switch ($action) { // Tool - reset progress for all users. case 'reset_course_progress': // Get a list of all users on this course. global $wpdb, $wpcwdb; $userList = $wpdb->get_col($wpdb->prepare("\n\t\t\t\t\t\tSELECT user_id \n\t\t\t\t\t\tFROM {$wpcwdb->user_courses}\n\t\t\t\t\t\tWHERE course_id = %d \n\t\t\t\t\t", $courseDetails->course_id)); $unitList = false; // Get all units for a course $courseMap = new WPCW_CourseMap(); $courseMap->loadDetails_byCourseID($courseDetails->course_id); $unitList = $courseMap->getUnitIDList_forCourse(); // Reset all users for this course. WPCW_users_resetProgress($userList, $unitList, $courseDetails, $courseMap->getUnitCount()); // Confirm it's complete. $page->showMessage(__('User progress for this course has been reset.', 'wp_courseware')); break; // Access changes // Access changes case 'grant_access_users_all': case 'grant_access_users_admins': WPCW_showPage_ModifyCourse_courseAccess_runAccessChanges($page, $action, $courseDetails); break; } // Add a link back to editing, as we've hidden that panel. printf('<p><a href="%s?page=WPCW_showPage_ModifyCourse&course_id=%d" class="button button-secondary">%s</a></p>', admin_url('admin.php'), $courseDetails->course_id, __('« Go back to editing the course settings', 'wp_courseware')); } else { global $wpcwdb; $formDetails = array('break_course_general' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab(false)), 'course_title' => array('label' => __('Course Title', 'wp_courseware'), 'type' => 'text', 'required' => true, 'cssclass' => 'wpcw_course_title', 'desc' => __('The title of your course.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 150, 'minlen' => 1, 'regexp' => '/^[^<>]+$/', 'error' => __('Please specify a name for your course, up to a maximum of 150 characters, just no angled brackets (< or >). Your trainees will be able to see this course title.', 'wp_courseware'))), 'course_desc' => array('label' => __('Course Description', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_desc', 'desc' => __('The description of this course. Your trainees will be able to see this course description.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 5000, 'minlen' => 1, 'error' => __('Please limit the description of your course to 5000 characters.', 'wp_courseware'))), 'course_opt_completion_wall' => array('label' => __('When do users see the next unit on the course?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'desc' => __('Can a user see all possible course units? Or must they complete previous units before seeing the next unit?', 'wp_courseware'), 'data' => array('all_visible' => __('<b>All Units Visible</b> - All units are visible regardless of completion progress.', 'wp_courseware'), 'completion_wall' => __('<b>Only Completed/Next Units Visible</b> - Only show units that have been completed, plus the next unit that the user can start.', 'wp_courseware'))), 'break_course_access' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'course_opt_user_access' => array('label' => __('Granting users access to this course', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'desc' => __('This setting allows you to set how users can access this course. They can either be given access automatically as soon as the user is created, or you can manually give them access. You can always manually remove access if you wish.', 'wp_courseware'), 'data' => array('default_show' => __('<b>Automatic</b> - All newly created users will be given access this course.', 'wp_courseware'), 'default_hide' => __('<b>Manual</b> - Users can only access course if you grant them access.', 'wp_courseware'))), 'break_course_messages' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'course_message_unit_complete' => array('label' => __('Message - Unit Complete', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_message', 'desc' => __('The message shown to a trainee once they\'ve <b>completed a unit</b>, which is displayed at the bottom of the unit page. HTML is OK.', 'wp_courseware'), 'rows' => 2, 'validate' => array('type' => 'string', 'maxlen' => 500, 'minlen' => 1, 'error' => __('Please limit message to 500 characters.', 'wp_courseware'))), 'course_message_course_complete' => array('label' => __('Message - Course Complete', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_message', 'desc' => __('The message shown to a trainee once they\'ve <b>completed the whole course</b>, which is displayed at the bottom of the unit page. HTML is OK.', 'wp_courseware'), 'rows' => 2, 'validate' => array('type' => 'string', 'maxlen' => 500, 'minlen' => 1, 'error' => __('Please limit message to 500 characters.', 'wp_courseware'))), 'course_message_unit_pending' => array('label' => __('Message - Unit Pending', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_message', 'desc' => __('The message shown to a trainee when they\'ve <b>yet to complete a unit</b>. This message is displayed at the bottom of the unit page, along with a button that says "<b>Mark as completed</b>". HTML is OK.', 'wp_courseware'), 'rows' => 2, 'validate' => array('type' => 'string', 'maxlen' => 500, 'minlen' => 1, 'error' => __('Please limit message to 500 characters.', 'wp_courseware'))), 'course_message_unit_no_access' => array('label' => __('Message - Access Denied', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_message', 'desc' => __('The message shown to a trainee they are <b>not allowed to access a unit</b>, because they are not allowed to <b>access the whole course</b>.', 'wp_courseware'), 'rows' => 2, 'validate' => array('type' => 'string', 'maxlen' => 500, 'minlen' => 1, 'error' => __('Please limit message to 500 characters.', 'wp_courseware'))), 'course_message_unit_not_yet' => array('label' => __('Message - Not Yet Available', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_message', 'desc' => __('The message shown to a trainee they are <b>not allowed to access a unit yet</b>, because they need to complete a previous unit.', 'wp_courseware'), 'rows' => 2, 'validate' => array('type' => 'string', 'maxlen' => 500, 'minlen' => 1, 'error' => __('Please limit message to 500 characters.', 'wp_courseware'))), 'course_message_unit_not_logged_in' => array('label' => __('Message - Not Logged In', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_message', 'desc' => __('The message shown to a trainee they are <b>not logged in</b>, and therefore cannot access the unit.', 'wp_courseware'), 'rows' => 2, 'validate' => array('type' => 'string', 'maxlen' => 500, 'minlen' => 1, 'error' => __('Please limit message to 500 characters.', 'wp_courseware'))), 'course_message_quiz_open_grading_blocking' => array('label' => __('Message - Open-Question Submitted - Blocking Mode', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_message', 'desc' => __('The message shown to a trainee they have submitted an answer to an <b>open-ended or upload question</b>, and you need to grade their answer <b>before they continue</b>.', 'wp_courseware'), 'rows' => 2, 'validate' => array('type' => 'string', 'maxlen' => 500, 'minlen' => 1, 'error' => __('Please limit message to 500 characters.', 'wp_courseware'))), 'course_message_quiz_open_grading_non_blocking' => array('label' => __('Message - Open-Question Submitted - Non-Blocking Mode', 'wp_courseware'), 'type' => 'textarea', 'required' => true, 'cssclass' => 'wpcw_course_message', 'desc' => __('The message shown to a trainee they have submitted an answer to an <b>open-ended or upload question</b>, and you need to grade their answer, but they can <b>continue anyway</b>.', 'wp_courseware'), 'rows' => 2, 'validate' => array('type' => 'string', 'maxlen' => 500, 'minlen' => 1, 'error' => __('Please limit message to 500 characters.', 'wp_courseware'))), 'break_course_notifications_from_details' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'course_from_email' => array('label' => __('Email From Address', 'wp_courseware'), 'type' => 'text', 'required' => true, 'cssclass' => 'wpcw_course_email', 'desc' => __('The email address that the email notifications should be from.<br/>Depending on your server\'s spam-protection set up, this may not appear in the outgoing emails.', 'wp_courseware'), 'validate' => array('type' => 'email', 'maxlen' => 150, 'minlen' => 1, 'error' => __('Please enter a valid email address.', 'wp_courseware'))), 'course_from_name' => array('label' => __('Email From Name', 'wp_courseware'), 'type' => 'text', 'required' => true, 'cssclass' => 'wpcw_course_email', 'desc' => __('The name used on the email notifications, which are sent to you and your trainees. <br/>Depending on your server\'s spam-protection set up, this may not appear in the outgoing emails.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 150, 'minlen' => 1, 'regexp' => '/^[^<>]+$/', 'error' => __('Please specify a from name, up to a maximum of 150 characters, just no angled brackets (< or >).', 'wp_courseware'))), 'course_to_email' => array('label' => __('Admin Notify Email Address', 'wp_courseware'), 'type' => 'text', 'required' => true, 'cssclass' => 'wpcw_course_email', 'desc' => __('The email address to send admin notifications to.', 'wp_courseware'), 'validate' => array('type' => 'email', 'maxlen' => 150, 'minlen' => 1, 'error' => __('Please enter a valid email address.', 'wp_courseware'))), 'break_course_notifications_user_module' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'email_complete_module_option_admin' => array('label' => __('Module Complete - Notify You?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_course_email_template_option', 'data' => array('send_email' => __('<b>Send me an email</b> - when one of your trainees has completed a module.', 'wp_courseware'), 'no_email' => __('<b>Don\'t send me an email</b> - when one of your trainees has completed a module.', 'wp_courseware'))), 'email_complete_module_option' => array('label' => __('Module Complete - Notify User?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_course_email_template_option', 'data' => array('send_email' => __('<b>Send Email</b> - to user when module has been completed.', 'wp_courseware'), 'no_email' => __('<b>Don\'t Send Email</b> - to user when module has been completed.', 'wp_courseware'))), 'email_complete_module_subject' => array('label' => __('Module Complete - Email Subject', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'cssclass' => 'wpcw_course_email_template_subject', 'rows' => 2, 'desc' => __('The <b>subject line</b> for the email sent to a user when they complete a <b>module</b>.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please limit the email subject to 300 characters.', 'wp_courseware'))), 'email_complete_module_body' => array('label' => __('Module Complete - Email Body', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'cssclass' => 'wpcw_course_email_template', 'desc' => __('The <b>template body</b> for the email sent to a user when they complete a <b>module</b>.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 5000, 'minlen' => 1, 'error' => __('Please limit the email body to 5000 characters.', 'wp_courseware'))), 'break_course_notifications_user_course' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'email_complete_course_option_admin' => array('label' => __('Course Complete - Notify You?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_course_email_template_option', 'data' => array('send_email' => __('<b>Send me an email</b> - when one of your trainees has completed the whole course.', 'wp_courseware'), 'no_email' => __('<b>Don\'t send me an email</b> - when one of your trainees has completed the whole course.', 'wp_courseware'))), 'email_complete_course_option' => array('label' => __('Course Complete - Notify User?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_course_email_template_option', 'data' => array('send_email' => __('<b>Send Email</b> - to user when the whole course has been completed.', 'wp_courseware'), 'no_email' => __('<b>Don\'t Send Email</b> - to user when the whole course has been completed.', 'wp_courseware'))), 'email_complete_course_subject' => array('label' => __('Course Complete - Email Subject', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'cssclass' => 'wpcw_course_email_template_subject', 'rows' => 2, 'desc' => __('The <b>subject line</b> for the email sent to a user when they complete <b>the whole course</b>.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please limit the email subject to 300 characters.', 'wp_courseware'))), 'email_complete_course_body' => array('label' => __('Course Complete - Email Body', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'cssclass' => 'wpcw_course_email_template', 'desc' => __('The <b>template body</b> for the email sent to a user when they complete <b>the whole course</b>.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 5000, 'minlen' => 1, 'error' => __('Please limit the email body to 5000 characters.', 'wp_courseware'))), 'break_course_notifications_user_grades' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'email_quiz_grade_option' => array('label' => __('Quiz Grade - Notify User?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'cssclass' => 'wpcw_course_email_template_option', 'data' => array('send_email' => __('<b>Send Email</b> - to user after a quiz is graded (automatically or by the instructor).', 'wp_courseware'), 'no_email' => __('<b>Don\'t Send Email</b> - to user when a quiz is graded.', 'wp_courseware'))), 'email_quiz_grade_subject' => array('label' => __('Quiz Graded - Email Subject', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'cssclass' => 'wpcw_course_email_template_subject', 'rows' => 2, 'desc' => __('The <b>subject line</b> for the email sent to a user when they receive a <b>grade for a quiz</b>.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please limit the email subject to 300 characters.', 'wp_courseware'))), 'email_quiz_grade_body' => array('label' => __('Quiz Graded - Email Body', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'cssclass' => 'wpcw_course_email_template', 'desc' => __('The <b>template body</b> for the email sent to a user when they receive a <b>grade for a quiz</b>.', 'wp_courseware'), 'rows' => 20, 'validate' => array('type' => 'string', 'maxlen' => 5000, 'minlen' => 1, 'error' => __('Please limit the email body to 5000 characters.', 'wp_courseware'))), 'break_course_notifications_user_final' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'email_complete_course_grade_summary_subject' => array('label' => __('Final Summary - Email Subject', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'cssclass' => 'wpcw_course_email_template_subject', 'rows' => 2, 'desc' => __('The <b>subject line</b> for the email sent to a user when they receive their <b>grade summary at the end of the course</b>.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please limit the email subject to 300 characters.', 'wp_courseware'))), 'email_complete_course_grade_summary_body' => array('label' => __('Final Summary - Email Body', 'wp_courseware'), 'type' => 'textarea', 'required' => false, 'rows' => 20, 'cssclass' => 'wpcw_course_email_template', 'desc' => __('The <b>template body</b> for the email sent to a user when they receive their <b>grade summary at the end of the course</b>.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 5000, 'minlen' => 1, 'error' => __('Please limit the email body to 5000 characters.', 'wp_courseware'))), 'break_course_certificates_user_course' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'course_opt_use_certificate' => array('label' => __('Enable certificates?', 'wp_courseware'), 'type' => 'radio', 'required' => true, 'data' => array('use_certs' => __('<b>Yes</b> - generate a PDF certificate when user completes this course.', 'wp_courseware'), 'no_certs' => __('<b>No</b> - don\'t generate a PDF certificate when user completes this course.', 'wp_courseware'))), 'break_course_certificates_user_tools' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML_tab()), 'course_tools_reset_all_users' => array('label' => __('Reset User Progess for this Course?', 'wp_courseware'), 'type' => 'custom', 'html' => sprintf('<a href="%s?page=WPCW_showPage_ModifyCourse&course_id=%d&action=reset_course_progress" class="button-primary" id="wpcw_course_btn_progress_reset_whole_course">%s</a><p>%s</p>', admin_url('admin.php'), $courseID, __('Reset All Users on this Course to the start', 'wp_courseware'), __('This button will reset all users who can access this course back to the beginning of the course. This deletes all grade data too.', 'wp_courseware'))), 'course_tools_user_access' => array('label' => __('Bulk-grant access to this course?', 'wp_courseware'), 'type' => 'custom', 'html' => sprintf('<a href="%s?page=WPCW_showPage_ModifyCourse&course_id=%d&action=grant_access_users_all" class="button-primary" id="wpcw_course_btn_access_all_existing_users">%s</a> <a href="%s?page=WPCW_showPage_ModifyCourse&course_id=%d&action=grant_access_users_admins" class="button-primary" id="wpcw_course_btn_access_all_existing_admins">%s</a> <p>%s</p>', admin_url('admin.php'), $courseID, __('All Existing Users (including Administrators)', 'wp_courseware'), admin_url('admin.php'), $courseID, __('Only All Existing Administrators', 'wp_courseware'), __('You can use the buttons above to grant all users access to this course. Depending on how many users you have, this may be a slow process.', 'wp_courseware')))); // Generate the tabs. $tabList = array('break_course_general' => array('label' => __('General Course Details', 'wp_courseware')), 'break_course_access' => array('label' => __('User Access', 'wp_courseware')), 'break_course_messages' => array('label' => __('User Messages', 'wp_courseware')), 'break_course_notifications_from_details' => array('label' => __('Email Address Details', 'wp_courseware')), 'break_course_notifications_user_module' => array('label' => __('Email Notifications - Module', 'wp_courseware')), 'break_course_notifications_user_course' => array('label' => __('Email Notifications - Course', 'wp_courseware')), 'break_course_notifications_user_grades' => array('label' => __('Email Notifications - Quiz Grades', 'wp_courseware')), 'break_course_notifications_user_final' => array('label' => __('Email Notifications - Final Summary', 'wp_courseware')), 'break_course_certificates_user_course' => array('label' => __('Certificates', 'wp_courseware')), 'break_course_certificates_user_tools' => array('label' => __('Course Access Tools', 'wp_courseware'))); // Remove reset fields if not appropriate. if (!$courseDetails) { // The tab unset($tabList['break_course_certificates_user_tools']); // The tool unset($formDetails['break_course_certificates_user_tools']); unset($formDetails['course_tools_reset_all_users']); } $form = new RecordsForm($formDetails, $wpcwdb->courses, 'course_id', false, 'wpcw_course_settings'); $form->customFormErrorMsg = __('Sorry, but unfortunately there were some errors saving the course details. Please fix the errors and try again.', 'wp_courseware'); $form->setAllTranslationStrings(WPCW_forms_getTranslationStrings()); // Set defaults if adding a new course if (!$courseDetails) { $form->loadDefaults(array('email_complete_module_subject' => EMAIL_TEMPLATE_COMPLETE_MODULE_SUBJECT, 'email_complete_course_subject' => EMAIL_TEMPLATE_COMPLETE_COURSE_SUBJECT, 'email_quiz_grade_subject' => EMAIL_TEMPLATE_QUIZ_GRADE_SUBJECT, 'email_complete_course_grade_summary_subject' => EMAIL_TEMPLATE_COURSE_SUMMARY_WITH_GRADE_SUBJECT, 'email_complete_module_body' => EMAIL_TEMPLATE_COMPLETE_MODULE_BODY, 'email_complete_course_body' => EMAIL_TEMPLATE_COMPLETE_COURSE_BODY, 'email_quiz_grade_body' => EMAIL_TEMPLATE_QUIZ_GRADE_BODY, 'email_complete_course_grade_summary_body' => EMAIL_TEMPLATE_COURSE_SUMMARY_WITH_GRADE_BODY, 'course_from_name' => get_bloginfo('name'), 'course_from_email' => get_bloginfo('admin_email'), 'course_to_email' => get_bloginfo('admin_email'), 'course_opt_completion_wall' => 'completion_wall', 'course_opt_user_access' => 'default_show', 'email_complete_course_option_admin' => 'send_email', 'email_complete_course_option' => 'send_email', 'email_complete_module_option_admin' => 'send_email', 'email_complete_module_option' => 'send_email', 'email_quiz_grade_option' => 'send_email', 'course_opt_use_certificate' => 'no_certs', 'course_message_unit_not_yet' => __("You need to complete the previous unit first.", 'wp_courseware'), 'course_message_unit_pending' => __("Have you completed this unit? Then mark this unit as completed.", 'wp_courseware'), 'course_message_unit_complete' => __("You have now completed this unit.", 'wp_courseware'), 'course_message_course_complete' => __("You have now completed the whole course. Congratulations!", 'wp_courseware'), 'course_message_unit_no_access' => __("Sorry, but you're not allowed to access this course.", 'wp_courseware'), 'course_message_unit_not_logged_in' => __('You cannot view this unit as you\'re not logged in yet.', 'wp_courseware'), 'course_message_quiz_open_grading_blocking' => __('Your quiz has been submitted for grading by the course instructor. Once your grade has been entered, you will be able access the next unit.', 'wp_courseware'), 'course_message_quiz_open_grading_non_blocking' => __('Your quiz has been submitted for grading by the course instructor. You have now completed this unit.', 'wp_courseware'))); } // 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 = __('Course details successfully created. ', 'wp_courseware') . $directionMsg; $form->msg_record_updated = __('Course details successfully updated. ', 'wp_courseware') . $directionMsg; $form->setPrimaryKeyValue($courseID); $form->setSaveButtonLabel(__('Save ALL Details', 'wp_courseware')); // Process form $formHTML = $form->getHTML(); // Show message about this course having quizzes that require a pass mark. // Need updated details for this. $courseDetails = WPCW_courses_getCourseDetails($courseID); if ($courseDetails && $courseDetails->course_opt_completion_wall == 'all_visible') { $quizzes = WPCW_quizzes_getAllBlockingQuizzesForCourse($courseDetails->course_id); // Count how many blocking quizzes there are. if ($quizzes && count($quizzes) > 0) { $quizCountMessage = sprintf(__('Currently <b>%d of your quizzes</b> are blocking process based on a percentage score <b>in this course</b>.', 'wp_courseware'), count($quizzes)); } else { $quizCountMessage = __('You do not currently have any blocking quizzes for this course.', 'wp_courseware'); } printf('<div id="message" class="wpcw_msg_info wpcw_msg"><b>%s</b> - %s<br/><br/> %s </div>', __('Important Note', 'wp_courseware'), __('You have selected <b>All Units Visible</b>. If you create a quiz blocking progress based on a percentage score, students will have access to the entire course regardless of quiz score.', 'wp_courseware'), $quizCountMessage); } // Generate the tabs echo WPCW_tabs_generateTabHeader($tabList, 'wpcw_courses_tabs', false); // Show the form echo $formHTML; echo '</div>'; // .wpcw_tab_wrapper } // end if not doing a tool manipulation. $page->showPageMiddle('20%'); // Include a link to delete the course if ($courseDetails) { $page->openPane('wpcw-deletion-course', __('Delete Course?', 'wp_courseware')); WPCW_showPage_ModifyCourse_deleteCourseButton($courseDetails); $page->closePane(); } // Email template tags here... $page->openPane('wpcw_docs_email_tags', __('Email Template Tags', 'wp_courseware')); printf('<h4 class="wpcw_docs_side_mini_hdr">%s</h4>', __('All Email Notifications', 'wp_courseware')); printf('<dl class="wpcw_email_tags">'); printf('<dt>{USER_NAME}</dt><dd>%s</dd>', __('The display name of the user.', 'wp_courseware')); printf('<dt>{SITE_NAME}</dt><dd>%s</dd>', __('The name of the website.', 'wp_courseware')); printf('<dt>{SITE_URL}</dt><dd>%s</dd>', __('The URL of the website.', 'wp_courseware')); printf('<dt>{COURSE_TITLE}</dt><dd>%s</dd>', __('The title of the course for the unit that\'s just been completed.', 'wp_courseware')); printf('<dt>{MODULE_TITLE}</dt><dd>%s</dd>', __('The title of the module for the unit that\'s just been completed.', 'wp_courseware')); printf('<dt>{MODULE_NUMBER}</dt><dd>%s</dd>', __('The number of the module for the unit that\'s just been completed.', 'wp_courseware')); printf('<dt>{CERTIFICATE_LINK}</dt><dd>%s</dd>', __('If the course has PDF certificates enabled, this is the link of the PDF certficate. (If there is no certificate or certificates are not enabled, this is simply blank)', 'wp_courseware')); printf('</dl>'); printf('<h4 class="wpcw_docs_side_mini_hdr">%s</h4>', __('Quiz Email Notifications Only', 'wp_courseware')); printf('<dl class="wpcw_email_tags">'); printf('<dt>{QUIZ_TITLE}</dt><dd>%s</dd>', __('The title of the quiz that has been graded.', 'wp_courseware')); printf('<dt>{QUIZ_GRADE}</dt><dd>%s</dd>', __('The overall percentage grade for a quiz.', 'wp_courseware')); printf('<dt>{QUIZ_GRADES_BY_TAG}</dt><dd>%s</dd>', __('Includes a breakdown of scores by tag if available.', 'wp_courseware')); printf('<dt>{QUIZ_TIME}</dt><dd>%s</dd>', __('If the quiz was timed, displays the time used to complete the quiz.', 'wp_courseware')); printf('<dt>{QUIZ_ATTEMPTS}</dt><dd>%s</dd>', __('Indicates the number of attempts for the quiz.', 'wp_courseware')); printf('<dt>{CUSTOM_FEEDBACK}</dt><dd>%s</dd>', __('Includes any custom feedback messages that have been triggered based on the user\'s specific results in the quiz.', 'wp_courseware')); printf('<dt>{QUIZ_RESULT_DETAIL}</dt><dd>%s</dd>', __('Any optional information relating to the result of the quiz, e.g. information about retaking the quiz.', 'wp_courseware')); printf('<dt>{UNIT_TITLE}</dt><dd>%s</dd>', __('The title of the unit that is associated with the quiz.', 'wp_courseware')); printf('<dt>{UNIT_URL}</dt><dd>%s</dd>', __('The URL of the unit that is associated with the quiz.', 'wp_courseware')); printf('</dl>'); printf('<h4 class="wpcw_docs_side_mini_hdr">%s</h4>', __('Final Summary Notifications Only', 'wp_courseware')); printf('<dl class="wpcw_email_tags">'); printf('<dt>{CUMULATIVE_GRADE}</dt><dd>%s</dd>', __('The overall cumulative grade that the user has scored from completing all quizzes on the course.', 'wp_courseware')); printf('<dt>{QUIZ_SUMMARY}</dt><dd>%s</dd>', __('The summary of each quiz, and what the user scored on each.', 'wp_courseware')); printf('</dl>'); $page->showPageFooter(); }