/** * Show the page where the user can set up the certificate settings. */ function WPCW_showPage_Certificates_load() { $page = new PageBuilder(true); $page->showPageHeader(__('Training Courses - Certificate Settings', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); $settingsFields = array('section_certificates_defaults' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML(__('Certificate Settings', 'wp_courseware'))), 'cert_signature_type' => array('label' => __('Signature Type', 'wp_courseware'), 'type' => 'radio', 'cssclass' => 'wpcw_cert_signature_type', 'required' => 'true', 'data' => array('text' => sprintf('<b>%s</b> - %s', __('Text', 'wp_courseware'), __('Just use text for the signature.', 'wp_courseware')), 'image' => sprintf('<b>%s</b> - %s', __('Image File', 'wp_courseware'), __('Use an image for the signature.', 'wp_courseware')))), 'cert_sig_text' => array('label' => __('Name to use for signature', 'wp_courseware'), 'type' => 'text', 'cssclass' => 'wpcw_cert_signature_type_text', 'desc' => __('The name to use for the signature area.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 150, 'minlen' => 1, 'regexp' => '/^[^<>]+$/', 'error' => __('Please enter the name to use for the signature area.', 'wp_courseware'))), 'cert_sig_image_url' => array('label' => __('Your Signature Image', 'wp_courseware'), 'cssclass' => 'wpcw_image_upload_field wpcw_cert_signature_type_image', 'type' => 'text', 'desc' => '• ' . __('The URL of your signature image. Using a transparent image is recommended.', 'wp_courseware') . '<br/>• ' . sprintf(__('The image must be <b>%d pixels wide, and %d pixels high</b> to render correctly. ', 'wp_courseware'), WPCW_CERTIFICATE_SIGNATURE_WIDTH_PX * 2, WPCW_CERTIFICATE_SIGNATURE_HEIGHT_PX * 2), 'validate' => array('type' => 'url', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please enter the URL of your signature image.', 'wp_courseware')), 'extrahtml' => sprintf('<a id="cert_sig_image_url_btn" href="#" class="wpcw_insert_image button-secondary" data-uploader_title="%s" data-uploader_btn_text="%s" data-target="cert_sig_image_url"><span class="wpcw_insert_image_img"></span> %s</a>', __('Choose an image to use for the signature image...', 'wp_courseware'), __('Select Image', 'wp_courseware'), __('Select Image', 'wp_courseware'))), 'cert_logo_enabled' => array('label' => __('Show your logo?', 'wp_courseware'), 'cssclass' => 'wpcw_cert_logo_enabled', 'type' => 'radio', 'required' => 'true', 'data' => array('cert_logo' => sprintf('<b>%s</b> - %s', __('Yes', 'wp_courseware'), __('Use your logo on the certificate.', 'wp_courseware')), 'no_cert_logo' => sprintf('<b>%s</b> - %s', __('No', 'wp_courseware'), __('Don\'t show a logo on the certificate.', 'wp_courseware')))), 'cert_logo_url' => array('label' => __('Your Logo Image', 'wp_courseware'), 'type' => 'text', 'cssclass' => 'wpcw_cert_logo_url wpcw_image_upload_field', 'desc' => '• ' . __('The URL of your logo image. Using a transparent image is recommended.', 'wp_courseware') . '<br/>• ' . sprintf(__('The image must be <b>%d pixels wide, and %d pixels</b> high to render correctly. ', 'wp_courseware'), WPCW_CERTIFICATE_LOGO_WIDTH_PX * 2, WPCW_CERTIFICATE_LOGO_HEIGHT_PX * 2), 'validate' => array('type' => 'url', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please enter the URL of your logo image.', 'wp_courseware')), 'extrahtml' => sprintf('<a id="cert_logo_url_btn" href="#" class="wpcw_insert_image button-secondary" data-uploader_title="%s" data-uploader_btn_text="%s" data-target="cert_logo_url"><span class="wpcw_insert_image_img"></span> %s</a>', __('Choose an image to use for your logo on the certificate...', 'wp_courseware'), __('Select Image', 'wp_courseware'), __('Select Image', 'wp_courseware'))), 'cert_background_type' => array('label' => __('Certificate Background', 'wp_courseware'), 'cssclass' => 'wpcw_cert_background_type', 'type' => 'radio', 'required' => 'true', 'data' => array('use_default' => sprintf('<b>%s</b> - %s', __('Built-in', 'wp_courseware'), __('Use the built-in certificate background.', 'wp_courseware')), 'use_custom' => sprintf('<b>%s</b> - %s', __('Custom', 'wp_courseware'), __('Use your own certificate background.', 'wp_courseware')))), 'cert_background_custom_url' => array('label' => __('Custom Background Image', 'wp_courseware'), 'type' => 'text', 'cssclass' => 'wpcw_cert_background_custom_url wpcw_image_upload_field', 'desc' => '• ' . __('The URL of your background image.', 'wp_courseware') . '<br/>• ' . sprintf(__('The background image must be <b>%d pixels wide, and %d pixels</b> high at <b>72 dpi</b> to render correctly. ', 'wp_courseware'), WPCW_CERTIFICATE_BG_WIDTH_PX, WPCW_CERTIFICATE_BG_HEIGHT_PX), 'validate' => array('type' => 'url', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please enter the URL of your certificate background image.', 'wp_courseware')), 'extrahtml' => sprintf('<a id="cert_background_custom_url_btn" href="#" class="wpcw_insert_image button-secondary" data-uploader_title="%s" data-uploader_btn_text="%s" data-target="cert_background_custom_url"><span class="wpcw_insert_image_img"></span> %s</a>', __('Choose an image to use for the certificate background...', 'wp_courseware'), __('Select Image', 'wp_courseware'), __('Select Image', 'wp_courseware')))); $settings = new SettingsForm($settingsFields, WPCW_DATABASE_SETTINGS_KEY, 'wpcw_form_settings_certificates'); $settings->setSaveButtonLabel(__('Save ALL Settings', 'wp_courseware')); $settings->msg_settingsSaved = __('Settings successfully saved.', 'wp_courseware'); $settings->msg_settingsProblem = __('There was a problem saving the settings.', 'wp_courseware'); $settings->setAllTranslationStrings(WPCW_forms_getTranslationStrings()); $settings->show(); // RHS Support Information $page->showPageMiddle('23%'); // Create a box where the admin can preview the certificates to see what they look like. $page->openPane('wpcw-certificates-preview', __('Preview Certificate', 'wp_courseware')); printf('<p>%s</p>', __('After saving the settings, you can preview the certificate using the button below. The preview opens in a new window.', 'wp_courseware')); printf('<div class="wpcw_btn_centre"><a href="%spdf_create_certificate.php?certificate=preview" target="_blank" class="button-primary">%s</a></div>', WPCW_plugin_getPluginPath(), __('Preview Certificate', 'wp_courseware')); $page->closePane(); WPCW_docs_showSupportInfo($page); WPCW_docs_showSupportInfo_News($page); WPCW_docs_showSupportInfo_Affiliate($page); $page->showPageFooter(); }
/** * Show the page where the user can set up the certificate settings. */ function WPCW_showPage_Certificates_load() { $page = new PageBuilder(true); $page->showPageHeader(__('Training Courses - Certificate Settings', 'wp_courseware'), '75%', WPCW_icon_getPageIconURL()); $settingsFields = array('section_certificates_defaults' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML(__('Certificate Settings', 'wp_courseware'))), 'cert_signature_type' => array('label' => __('Signature Type', 'wp_courseware'), 'type' => 'radio', 'cssclass' => 'wpcw_cert_signature_type', 'required' => 'true', 'data' => array('text' => sprintf('<b>%s</b> - %s', __('Text', 'wp_courseware'), __('Just use text for the signature.', 'wp_courseware')), 'image' => sprintf('<b>%s</b> - %s', __('Image File', 'wp_courseware'), __('Use an image for the signature.', 'wp_courseware')))), 'cert_sig_text' => array('label' => __('Name to use for signature', 'wp_courseware'), 'type' => 'text', 'cssclass' => 'wpcw_cert_signature_type_text', 'desc' => __('The name to use for the signature area.', 'wp_courseware'), 'validate' => array('type' => 'string', 'maxlen' => 150, 'minlen' => 1, 'regexp' => '/^[^<>]+$/', 'error' => __('Please enter the name to use for the signature area.', 'wp_courseware'))), 'cert_sig_image_url' => array('label' => __('Your Signature Image', 'wp_courseware'), 'cssclass' => 'wpcw_image_upload_field wpcw_cert_signature_type_image', 'type' => 'text', 'desc' => '• ' . __('The URL of your signature image. Using a transparent image is recommended.', 'wp_courseware') . '<br/>• ' . sprintf(__('The image must be <b>%d pixels wide, and %d pixels high</b> to render correctly. ', 'wp_courseware'), WPCW_CERTIFICATE_SIGNATURE_WIDTH_PX * 2, WPCW_CERTIFICATE_SIGNATURE_HEIGHT_PX * 2), 'validate' => array('type' => 'url', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please enter the URL of your signature image.', 'wp_courseware')), 'extrahtml' => sprintf('<a id="cert_sig_image_url_btn" href="#" class="wpcw_insert_image button-secondary" data-uploader_title="%s" data-uploader_btn_text="%s" data-target="cert_sig_image_url"><span class="wpcw_insert_image_img"></span> %s</a>', __('Choose an image to use for the signature image...', 'wp_courseware'), __('Select Image', 'wp_courseware'), __('Select Image', 'wp_courseware'))), 'cert_logo_enabled' => array('label' => __('Show your logo?', 'wp_courseware'), 'cssclass' => 'wpcw_cert_logo_enabled', 'type' => 'radio', 'required' => 'true', 'data' => array('cert_logo' => sprintf('<b>%s</b> - %s', __('Yes', 'wp_courseware'), __('Use your logo on the certificate.', 'wp_courseware')), 'no_cert_logo' => sprintf('<b>%s</b> - %s', __('No', 'wp_courseware'), __('Don\'t show a logo on the certificate.', 'wp_courseware')))), 'cert_logo_url' => array('label' => __('Your Logo Image', 'wp_courseware'), 'type' => 'text', 'cssclass' => 'wpcw_cert_logo_url wpcw_image_upload_field', 'desc' => '• ' . __('The URL of your logo image. Using a transparent image is recommended.', 'wp_courseware') . '<br/>• ' . sprintf(__('The image must be <b>%d pixels wide, and %d pixels</b> high to render correctly. ', 'wp_courseware'), WPCW_CERTIFICATE_LOGO_WIDTH_PX * 2, WPCW_CERTIFICATE_LOGO_HEIGHT_PX * 2), 'validate' => array('type' => 'url', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please enter the URL of your logo image.', 'wp_courseware')), 'extrahtml' => sprintf('<a id="cert_logo_url_btn" href="#" class="wpcw_insert_image button-secondary" data-uploader_title="%s" data-uploader_btn_text="%s" data-target="cert_logo_url"><span class="wpcw_insert_image_img"></span> %s</a>', __('Choose an image to use for your logo on the certificate...', 'wp_courseware'), __('Select Image', 'wp_courseware'), __('Select Image', 'wp_courseware'))), 'cert_background_type' => array('label' => __('Certificate Background', 'wp_courseware'), 'cssclass' => 'wpcw_cert_background_type', 'type' => 'radio', 'required' => 'true', 'data' => array('use_default' => sprintf('<b>%s</b> - %s', __('Built-in', 'wp_courseware'), __('Use the built-in certificate background.', 'wp_courseware')), 'use_custom' => sprintf('<b>%s</b> - %s', __('Custom', 'wp_courseware'), __('Use your own certificate background.', 'wp_courseware')))), 'cert_background_custom_url' => array('label' => __('Custom Background Image', 'wp_courseware'), 'type' => 'text', 'cssclass' => 'wpcw_cert_background_custom_url wpcw_image_upload_field', 'desc' => '• ' . __('The URL of your background image.', 'wp_courseware') . '<br/>• ' . sprintf(__('The background image must be <b>%d pixels wide, and %d pixels</b> high at <b>72 dpi</b> to render correctly. ', 'wp_courseware'), WPCW_CERTIFICATE_BG_WIDTH_PX, WPCW_CERTIFICATE_BG_HEIGHT_PX), 'validate' => array('type' => 'url', 'maxlen' => 300, 'minlen' => 1, 'error' => __('Please enter the URL of your certificate background image.', 'wp_courseware')), 'extrahtml' => sprintf('<a id="cert_background_custom_url_btn" href="#" class="wpcw_insert_image button-secondary" data-uploader_title="%s" data-uploader_btn_text="%s" data-target="cert_background_custom_url"><span class="wpcw_insert_image_img"></span> %s</a>', __('Choose an image to use for the certificate background...', 'wp_courseware'), __('Select Image', 'wp_courseware'), __('Select Image', 'wp_courseware'))), 'section_encodings' => array('type' => 'break', 'html' => WPCW_forms_createBreakHTML(__('Language and Encoding Settings', 'wp_courseware'))), 'certificate_encoding' => array('label' => __('Certificate Encoding', 'wp_courseware'), 'type' => 'select', 'required' => true, 'desc' => __('Choose a codepage encoding that matches your language to ensure certificates render correctly. You may need an encoding other than <code>ISO-8859-1</code> if you are using a non-English language.', 'wp_courseware'), 'data' => array('ISO-8859-1' => __('ISO-8859-1 - Latin alphabet - North America, Western Europe, Latin America, etc. (Default)', 'wp_courseware'), 'ISO-8859-2' => __('ISO-8859-2 - Latin alphabet 2 - Eastern Europe.', 'wp_courseware'), 'ISO-8859-3' => __('ISO-8859-3 - Latin alphabet 3 - SE Europe, Esperanto', 'wp_courseware'), 'ISO-8859-4' => __('ISO-8859-4 - Latin alphabet 4 - Scandinavia/Baltics', 'wp_courseware'), 'ISO-8859-5' => __('ISO-8859-5 - Latin/Cyrillic - Bulgarian, Belarusian, Russian and Macedonian', 'wp_courseware'), 'ISO-8859-6' => __('ISO-8859-6 - Latin/Arabic - Arabic languages', 'wp_courseware'), 'ISO-8859-7' => __('ISO-8859-7 - Latin/Greek - modern Greek language', 'wp_courseware'), 'ISO-8859-8' => __('ISO-8859-8 - Latin/Hebrew - Hebrew languages', 'wp_courseware'), 'ISO-8859-9' => __('ISO-8859-9 - Latin 5 part 9 - Turkish languages', 'wp_courseware'), 'ISO-8859-10' => __('ISO-8859-10 - Latin 6 Lappish, Nordic, Eskimo - The Nordic languages', 'wp_courseware'), 'ISO-8859-15' => __('ISO-8859-15 - Latin 9 (aka Latin 0) - Similar to ISO 8859-1', 'wp_courseware')))); $settings = new SettingsForm($settingsFields, WPCW_DATABASE_SETTINGS_KEY, 'wpcw_form_settings_certificates'); $settings->setSaveButtonLabel(__('Save ALL Settings', 'wp_courseware')); $settings->msg_settingsSaved = __('Settings successfully saved.', 'wp_courseware'); $settings->msg_settingsProblem = __('There was a problem saving the settings.', 'wp_courseware'); $settings->setAllTranslationStrings(WPCW_forms_getTranslationStrings()); $settings->show(); // RHS Support Information $page->showPageMiddle('23%'); // Create a box where the admin can preview the certificates to see what they look like. $page->openPane('wpcw-certificates-preview', __('Preview Certificate', 'wp_courseware')); printf('<p>%s</p>', __('After saving the settings, you can preview the certificate using the button below. The preview opens in a new window.', 'wp_courseware')); printf('<div class="wpcw_btn_centre"><a href="%spdf_create_certificate.php?certificate=preview" target="_blank" class="button-primary">%s</a></div>', WPCW_plugin_getPluginPath(), __('Preview Certificate', 'wp_courseware')); $page->closePane(); WPCW_docs_showSupportInfo($page); WPCW_docs_showSupportInfo_News($page); WPCW_docs_showSupportInfo_Affiliate($page); $page->showPageFooter(); }
/** * Creates the course unit post type. */ function WPCW_plugin_registerCustomPostTypes() { $labels = array('name' => __('Course Units', 'wp_courseware'), 'singular_name' => __('Course Unit', 'wp_courseware'), 'add_new' => __('Add New', 'wp_courseware'), 'add_new_item' => __('Add New Course Unit', 'wp_courseware'), 'edit_item' => __('Edit Course Unit', 'wp_courseware'), 'new_item' => __('New Course Unit', 'wp_courseware'), 'view_item' => __('View Course Unit', 'wp_courseware'), 'search_items' => __('Search Course Units', 'wp_courseware'), 'not_found' => __('No course units found', 'wp_courseware'), 'not_found_in_trash' => __('No course units found in Trash', 'wp_courseware'), 'parent_item_colon' => __('Parent Course Unit:', 'wp_courseware'), 'menu_name' => __('Course Units', 'wp_courseware')); $args = array('labels' => $labels, 'hierarchical' => false, 'supports' => array('title', 'editor', 'revisions'), 'public' => true, 'show_ui' => true, 'show_in_menu' => true, 'menu_position' => 100, 'menu_icon' => WPCW_plugin_getPluginPath() . 'img/icon_training_16.png', 'show_in_nav_menus' => false, 'publicly_queryable' => true, 'exclude_from_search' => false, 'has_archive' => false, 'query_var' => true, 'can_export' => true, 'rewrite' => false, 'capability_type' => 'post', 'menu_position' => WPCW_MENU_POSITION + 1); register_post_type('course_unit', $args); }
/** * Output the form that allows questions to be configured. */ function editForm_toString() { $answerList = false; if ($this->quizItem->question_data_answers) { $answerList = WPCW_quizzes_decodeAnswers($this->quizItem->question_data_answers); } $html = false; // Extra CSS for errors $errorClass_Question = false; $errorClass_CorAnswer = false; // Error Check - Have we got an issue with a lack of question? if ($this->showErrors) { if (!$this->quizItem->question_question) { $errorClass_Question = 'wpcw_quiz_missing'; $this->gotError = true; } if ($this->needCorrectAnswers && !$this->quizItem->question_correct_answer) { $errorClass_CorAnswer = 'wpcw_quiz_missing'; $this->gotError = true; } } // Track columns needed to show question details $columnCount = 4; // Render just the question area $html .= sprintf('<li id="wpcw_quiz_details_%s" class="%s"><table class="wpcw_quiz_details_questions_wrap" cellspacing="0">', $this->quizItem->question_id, $this->cssClasses); // Details of the question - top of the question details. $html .= $this->getSection_processHeader($columnCount); // Main question details here... $html .= sprintf('<tr class="wpcw_quiz_row_question %s">', $errorClass_Question); $html .= sprintf('<th>%s</th>', __('Question', 'wp_courseware')); $html .= sprintf('<td>'); $html .= sprintf('<textarea name="question_question_%s">%s</textarea>', $this->quizItem->question_id, htmlspecialchars($this->quizItem->question_question)); $html .= sprintf('<input type="hidden" name="question_type_%s" value="multi" />', $this->quizItem->question_id); // Field storing order of question among other questions $html .= sprintf('<input type="hidden" name="question_order_%s" value="%s" class="wpcw_question_hidden_order" />', $this->quizItem->question_id, $this->quizItem->question_order + 0); $html .= sprintf('</td>'); // Only show column if need correct answers. $html .= sprintf('<td class="wpcw_quiz_details_tick_correct wpcw_quiz_only_td">%s</td>', __('Correct<br/>Answer?', 'wp_courseware')); // Column for add/remove buttons $html .= '<td> </td>'; $html .= sprintf('</tr>'); // Render the section that allows an image to be shown. $html .= $this->getSection_showImageField($columnCount); // Render the field that allows answers to be randomized $html .= $this->getSection_showRandomizeAnswersField($columnCount); // Render the list of answers if we have any. if ($answerList) { $count = 0; $odd = true; foreach ($answerList as $answerItem) { // Extract image if available $answerItemImageVal = WPCW_arrays_getValue($answerItem, 'image'); // Exract the answer if available $answerItemVal = trim($answerItem['answer']); $count++; // Show an error if the field is still blank. $errorClass_Answer = false; if ($this->showErrors) { // Check that answer contains some characters. if (strlen($answerItemVal) == 0) { $errorClass_Answer = 'wpcw_quiz_missing'; $this->gotError = true; } } // Add 'data-answer-id' field to store the ID of this row, and other rows that match this. $html .= sprintf('<tr class="wpcw_quiz_row_answer %s %s" data-answer-id="%d">', $errorClass_Answer, $odd ? 'alternate' : '', $count); $html .= sprintf('<th>%s <span>%d</span></th>', __('Answer', 'wp_courseware'), $count); $html .= sprintf('<td><input type="text" name="question_answer_%s[%d]" value="%s" /></td>', $this->quizItem->question_id, $count, htmlspecialchars($answerItemVal)); // Correct answer column $html .= sprintf('<td class="wpcw_quiz_details_tick_correct wpcw_quiz_only_td"> <input type="radio" name="question_answer_sel_%s" value="%s" %s /> </td>', $this->quizItem->question_id, $count, $this->quizItem->question_correct_answer == $count ? 'checked="checked"' : false); // Buttons for add/remove questions $html .= sprintf(' <td class="wpcw_quiz_add_rem"> <a href="#" title="%s" class="wpcw_question_add"><img src="%simg/icon_add_32.png" /></a> <a href="#" title="%s" class="wpcw_question_remove"><img src="%simg/icon_remove_32.png" /></a> </td>', __('Add a new answer...', 'wp_courseware'), WPCW_plugin_getPluginPath(), __('Remove this answer...', 'wp_courseware'), WPCW_plugin_getPluginPath()); $html .= sprintf('</tr>'); // Add the image URL for this answer - added as a new row. $html .= sprintf('<tr class="wpcw_quiz_row_answer_image wpcw_quiz_row_answer_image_%d %s %s">', $count, $errorClass_Answer, $odd ? 'alternate' : ''); $html .= sprintf('<th>%s <span class="wpcw_inner_hint">%s</span></th>', __('Answer Image URL', 'wp_courseware'), __('(Optional) ', 'wp_courseware')); $html .= '<td>'; // Field name - needs to use underscore, as square brackets break the jQuery to find the target. $thisAnswerFieldName = 'question_answer_image_' . $this->quizItem->question_id . '_' . $count; // The URL field. $html .= sprintf('<input type="text" name="question_answer_image_%s[%d]" id="%s" value="%s" />', $this->quizItem->question_id, $count, $thisAnswerFieldName, $answerItemImageVal); // The insert button. $html .= sprintf('<span class="wpcw_insert_image_wrap"><a href="#" class="button wpcw_insert_image" data-uploader_title="%s" data-uploader_btn_text="%s" data-target="%s" title="%s"><span class="wpcw_insert_image_img"></span> %s</a></span>', __('Choose an image for this answer...', 'wp_courseware'), __('Select Image...', 'wp_courseware'), $thisAnswerFieldName, __('Select Image', 'wp_courseware'), __('Select Image', 'wp_courseware')); $html .= '</td>'; // Filler for the remaining space $html .= '<td colspan="2"></td>'; $html .= sprintf('</tr>'); $odd = !$odd; } } // Extra fields at the bottom of a question. $html .= $this->getSection_processFooter($columnCount); // All done $html .= sprintf('</table></li>'); return $html; }
/** * Output the form that allows questions to be configured. */ function editForm_toString() { $answerList = false; if ($this->quizItem->question_answers) { $answerList = explode("\n", $this->quizItem->question_answers); } $html = false; // Extra CSS for errors $errorClass_Question = false; $errorClass_CorAnswer = false; // Error Check - Have we got an issue with a lack of question? if ($this->showErrors) { if (!$this->quizItem->question_question) { $errorClass_Question = 'wpcw_quiz_missing'; $this->gotError = true; } if ($this->needCorrectAnswers && !$this->quizItem->question_correct_answer) { $errorClass_CorAnswer = 'wpcw_quiz_missing'; $this->gotError = true; } } // Track columns needed to show question details $columnCount = 3; // Render just the question area $html .= sprintf('<li id="wpcw_quiz_details_%s" class="%s"><table class="wpcw_quiz_details_questions_wrap" cellspacing="0">', $this->quizItem->question_id, $this->cssClasses); $html .= sprintf('<tr class="wpcw_quiz_row_question">'); $html .= sprintf('<th class="%s">%s</th>', $errorClass_Question, __('Question', 'wp_courseware')); $html .= sprintf('<td class="%s">', $errorClass_Question); $html .= sprintf('<input type="text" name="question_question_%s" value="%s" />', $this->quizItem->question_id, $this->quizItem->question_question); $html .= sprintf('<input type="hidden" name="question_type_%s" value="multi" />', $this->quizItem->question_id); // Field storing order of question among other questions $html .= sprintf('<input type="hidden" name="question_order_%s" value="%s" class="wpcw_question_hidden_order" />', $this->quizItem->question_id, $this->quizItem->question_order + 0); $html .= sprintf('</td>'); // Only show column if need correct answers. if ($this->needCorrectAnswers) { $html .= sprintf('<td class="wpcw_quiz_details_tick_correct %s">%s</td>', $errorClass_CorAnswer, __('Correct<br/>Answer?', 'wp_courseware')); $columnCount++; } // Column for add/remove buttons $html .= '<td> </td>'; $html .= sprintf('</tr>'); // Render the list of answers if we have any. if ($answerList) { $count = 0; $odd = true; foreach ($answerList as $answerItem) { $answerItem = trim($answerItem); $count++; // Show an error if the field is still blank. $errorClass_Answer = false; if ($this->showErrors) { // Check that answer contains some characters. if (strlen($answerItem) == 0) { $errorClass_Answer = 'wpcw_quiz_missing'; $this->gotError = true; } } $html .= sprintf('<tr class="wpcw_quiz_row_answer %s">', $errorClass_Answer); $html .= sprintf('<th>%s <span>%d</span></th>', __('Answer', 'wp_courseware'), $count); $html .= sprintf('<td><input type="text" name="question_answer_%s[%d]" value="%s" /></td>', $this->quizItem->question_id, $count, $answerItem); // Correct answer column if ($this->needCorrectAnswers) { $html .= sprintf('<td class="wpcw_quiz_details_tick_correct %s"> <input type="radio" name="question_answer_sel_%s" value="%s" %s /> </td>', $errorClass_CorAnswer, $this->quizItem->question_id, $count, $this->quizItem->question_correct_answer == $count ? 'checked="checked"' : false); } // Buttons for add/remove questions $html .= sprintf(' <td class="wpcw_quiz_add_rem"> <a href="#" title="%s" class="wpcw_question_add"><img src="%simg/icon_add_32.png" /></a> <a href="#" title="%s" class="wpcw_question_remove"><img src="%simg/icon_remove_32.png" /></a> </td>', __('Add a new answer...', 'wp_courseware'), WPCW_plugin_getPluginPath(), __('Remove this answer...', 'wp_courseware'), WPCW_plugin_getPluginPath()); $html .= sprintf('</tr>'); $odd = !$odd; } } // Add icons for adding or removing a question. $html .= $this->getActionButtons($columnCount); // All done $html .= sprintf('</table></li>'); return $html; }
/** * Shows the quiz for the unit, based on the type being shown. * * @param Boolean $showErrorsOnForm If true, show the errors on the form, acts as an override to disable showing errors if they are not wanted. * * @return String The HTML that renders the quiz for answering. */ function render_quizzes_handleQuizRendering($showErrorsOnForm = true) { // Hopefully not needed, but just in case. if (!$this->unitQuizDetails) { return false; } // Reload all raw answers user has created so far (if we have anything so far) if (!empty($this->unitQuizProgress) && 'incomplete' == $this->unitQuizProgress->quiz_paging_status) { $this->fetch_quizzes_loadRawAnswersSoFarForThisQuiz($this->unitQuizProgress->quiz_data); } // Render the wrapper for the quiz using the pending message section // Use the Quiz ID and Unit ID to validate permissions. $html = sprintf('<div class="wpcw_fe_quiz_box_wrap" id="wpcw_fe_quiz_complete_%d_%d">', $this->unitPost->ID, $this->unitQuizDetails->quiz_id); // Are we going to show the answers on a single for as part of the review? if ($this->check_paging_shouldWeShowReviewPage_rightNow()) { // To do, show a message here about reviewing answers... $html .= WPCW_UnitFrontend::message_createMessage_warning(__('You can now review your answers before submitting them.', 'wp_courseware')); } // Use any raw selection data that we have so far to pre-fill answers. $resultsList = $this->unchecked_QuizAnswersToGrade; // enctype="multipart/form-data" for file uploads.. // data-wpcw_expired="false" - this is used by the timer to indicate if the timer has expired or not. $html .= sprintf('<form method="post" enctype="multipart/form-data" id="quiz_complete_%d_%d" data-wpcw_unit="%d" data-wpcw_quiz="%d" data-wpcw_expired="false">', $this->unitPost->ID, $this->unitQuizDetails->quiz_id, $this->unitPost->ID, $this->unitQuizDetails->quiz_id); $html .= '<div class="wpcw_fe_quiz_box wpcw_fe_quiz_box_pending">'; // #### 1 - Quiz Title - constant for all quizzes $html .= sprintf('<div class="wpcw_fe_quiz_title">%s</div>', $this->unitQuizDetails->quiz_title); // #### 2 - Pass mark - just needed for blocking quizes if ('quiz_block' == $this->unitQuizDetails->quiz_type) { $totalQs = count($this->unitQuizDetails->questions); $passQs = ceil($this->unitQuizDetails->quiz_pass_mark / 100 * $totalQs); $html .= '<div class="wpcw_fe_quiz_pass_mark">'; $html .= sprintf(__('You\'ll need to correctly answer at least <b>%d of the %d</b> questions below (<b>at least %d%%</b>) to progress to the next unit.', 'wp_courseware'), $passQs, $totalQs, $this->unitQuizDetails->quiz_pass_mark); $html .= '</div>'; } // #### 3 - The actual question form. if (!empty($this->unitQuizDetails->questions)) { $questionNum = 1; $showQuestions = true; // Timer Mode if ('use_timer' == $this->unitQuizDetails->quiz_timer_mode) { // We've not started the quiz yet, so we show the begin test button. if (empty($this->unitQuizProgress) || 'retake_waiting' == $this->unitQuizProgress->quiz_next_step_type) { $showQuestions = false; $html .= '<div class="wpcw_fe_quiz_q_hdr"></div>'; // Begin Quiz $html .= sprintf(' <div class="wpcw_fe_quiz_begin_quiz"> <div class="wpcw_fe_quiz_begin_quiz_hdr">%s</div> <a href="#" class="fe_btn fe_btn_completion" id="wpcw_fe_quiz_begin_quiz" data-wpcw_quiz="%d" data-wpcw_unit="%d" >%s</a> <div class="wpcw_fe_submit_loader wpcw_loader"> <img src="%simg/ajax_loader.gif" /> </div> </div>', sprintf(__('You have <b>%s</b> to complete this quiz...', 'wp_coursware'), WPCW_time_convertMinutesToHumanLabel($this->unitQuizDetails->quiz_timer_mode_limit)), $this->unitQuizDetails->quiz_id, $this->unitPost->ID, __('Begin Quiz...', 'wp_courseware'), WPCW_plugin_getPluginPath()); } else { // Total time in seconds for this quiz $timerDetails_secondsLeft = $allowedTime = 60 * $this->unitQuizDetails->quiz_timer_mode_limit; // What time do we have left? $timeSoFar = strtotime($this->unitQuizProgress->quiz_started_date); $timeNow = current_time('timestamp'); // We've started the quiz when the time so far is > 0 if ($timeSoFar > 0) { $timerDetails_secondsLeft = $allowedTime - ($timeNow - $timeSoFar); } // Show the timer if we have time left. $html .= sprintf('<div id="wpcw_fe_timer_countdown" data-time_left="%d">%s</div>', $timerDetails_secondsLeft, WPCW_time_convertSecondsToHumanLabel($timerDetails_secondsLeft)); } } if ($showQuestions) { // We're paging, so check what question or questions to show next. if ($this->check_paging_areWePagingQuestions()) { // Stores the index of the next question to show $questionToShowIndex = $this->fetch_paging_getQuestionIndex(); $question = $this->fetch_paging_getQuestion($questionToShowIndex); // Show progress of user through the questions. $html .= sprintf('<div class="wpcw_fe_paging_progress">%s</div>', sprintf(__('Question %d of %d', 'wp_courseware'), $questionToShowIndex + 1, $this->fetch_paging_getQuestionCount())); // Header before questions (but show progress before the header line). $html .= '<div class="wpcw_fe_quiz_q_hdr"></div>'; // Show the answer later button. if ($this->check_paging_shouldWeShowAnswerLaterButton()) { $html .= sprintf('<div class="wpcw_fe_quiz_answer_later"><a href="#" class="fe_btn fe_btn_small fe_btn_navigation" id="wpcw_fe_quiz_answer_later">%s</a></div>', __('Answer Later...', 'wp_courseware')); } // Render just this question $html .= $this->render_quizzes_handleQuizRendering_singleQuestion($question, $resultsList, $showErrorsOnForm, $questionToShowIndex + 1, true, 0); // Work out what caption to show for the submit button. Change this if we're about to // submit the answers for the final question or review our answers. $buttonCaption = __('Save & Next Question »', 'wp_courseware'); // Are we showing the last incomplete question (and we're nearly complete) if ($this->unitQuizProgress && $this->unitQuizProgress->quiz_paging_incomplete <= 1 && $this->check_paging_isThisTheLastIncompleteQuestion($question->question_id)) { // We appear to be on the last question. Are we going to review too? if ($this->check_paging_shouldWeShowReviewPage()) { $buttonCaption = __('Save & Review Answers »', 'wp_courseware'); } else { $buttonCaption = __('Submit Answers', 'wp_courseware'); } } // Previous button - created if required. Using a button rather than a link to ensure the buttons look right when side-by-side. $buttonPreviousClicker = false; if ($this->check_paging_shouldWeShowPreviousButton()) { $buttonPreviousClicker = sprintf('<input type="submit" class="fe_btn fe_btn_completion btn_completion" id="fe_btn_quiz_previous" name="previous_question" value="%s">', __('« Previous Question', 'wp_courseware')); } // #### 4A - The navigation buttons $html .= sprintf('<div class="wpcw_fe_quiz_submit wpcw_fe_quiz_submit_data"> %s <div class="wpcw_fe_submit_loader wpcw_loader"> <img src="%simg/ajax_loader.gif" /> </div> %s <input type="submit" class="fe_btn fe_btn_completion btn_completion" id="fe_btn_quiz_next" name="submit" value="%s"> </div>', WPCW_content_progressBar(0, 'wpcw_fe_upload_progress'), WPCW_plugin_getPluginPath(), $buttonPreviousClicker, $buttonCaption); } else { // Header before questions $html .= '<div class="wpcw_fe_quiz_q_hdr"></div>'; $questionIndex = 0; foreach ($this->unitQuizDetails->questions as $question) { $html .= $this->render_quizzes_handleQuizRendering_singleQuestion($question, $resultsList, $showErrorsOnForm, $questionNum++, false, $questionIndex++); } // #### 4B - The submit answers button. //<a href="#" class="fe_btn fe_btn_completion btn_completion" id="quiz_complete_%d_%d">%s</a> $html .= sprintf('<div class="wpcw_fe_quiz_submit wpcw_fe_quiz_submit_data"> %s <div class="wpcw_fe_submit_loader wpcw_loader"> <img src="%simg/ajax_loader.gif" /> </div> <input type="submit" class="fe_btn fe_btn_completion btn_completion" name="submit" value="%s"> </div>', WPCW_content_progressBar(0, 'wpcw_fe_upload_progress'), WPCW_plugin_getPluginPath(), __('Submit Answers', 'wp_courseware')); } // end of check for paging. } // end of check of showing questions (e.g. timer mode) } // end of question check $html .= '</div>'; // .wpcw_fe_quiz_box $html .= '</form>'; $html .= '</div>'; // .wpcw_fe_quiz_box_wrap return $html; }
/** * Return a URL to download a certificate. * * @param String $accessKey The access key for the certificate. * @return String The full URL to the certificate. */ function WPCW_certificate_generateLink($accessKey) { return apply_filters('wpcw_certificate_generated_url', WPCW_plugin_getPluginPath() . 'pdf_create_certificate.php?certificate=' . $accessKey); }
/** * Shows the quiz for the unit, based on the type being shown. * * @param Integer $unitID The ID of the unit that's currently pending. * @param Object $quizDetails The details of the quiz to show. * @param Array $resultsList The list of checked answers, wrong answers, and error messages for the quiz form. * * @return String The HTML that renders the quiz for answering. */ function WPCW_quizzes_handleQuizRendering($unitID, $quizDetails, $resultsList = false) { // Hopefully not needed, but just in case. if (!$quizDetails) { return false; } // Create an array so that we can use isset($answerList['key']). if (!$resultsList) { $resultsList = array('answer_list' => array(), 'wrong_answer_list' => array(), 'error_answer_list' => array()); } // Render the wrapper for the quiz using the pending message section // Use the Quiz ID and Unit ID to validate permissions. $html = sprintf('<div class="wpcw_fe_quiz_box_wrap" id="wpcw_fe_quiz_complete_%d_%d">', $unitID, $quizDetails->quiz_id); // enctype="multipart/form-data" for file uploads. $html .= sprintf('<form method="post" enctype="multipart/form-data" id="quiz_complete_%d_%d">', $unitID, $quizDetails->quiz_id); $html .= '<div class="wpcw_fe_quiz_box wpcw_fe_quiz_box_pending">'; // #### 1 - Quiz Title - constant for all quizzes $html .= sprintf('<div class="wpcw_fe_quiz_title">%s</div>', $quizDetails->quiz_title); // #### 2 - Pass mark - just needed for blocking quizes if ('quiz_block' == $quizDetails->quiz_type) { $totalQs = count($quizDetails->questions); $passQs = ceil($quizDetails->quiz_pass_mark / 100 * $totalQs); $html .= '<div class="wpcw_fe_quiz_pass_mark">'; $html .= sprintf(__('You\'ll need to correctly answer at least <b>%d of the %d</b> questions below (<b>at least %d%%</b>) to progress to the next unit.', 'wp_courseware'), $passQs, $totalQs, $quizDetails->quiz_pass_mark); $html .= '</div>'; } // Header before questions $html .= '<div class="wpcw_fe_quiz_q_hdr"></div>'; // #### 3 - The actual question form. if ($quizDetails->questions && count($quizDetails->questions) > 0) { $questionNum = 1; foreach ($quizDetails->questions as $question) { // See if we want to show an answer $selectAnswer = false; if (isset($resultsList['answer_list'][$question->question_id])) { $selectAnswer = $resultsList['answer_list'][$question->question_id]; } switch ($question->question_type) { case 'multi': $quObj = new WPCW_quiz_MultipleChoice($question); break; case 'open': $quObj = new WPCW_quiz_OpenEntry($question); break; case 'upload': $quObj = new WPCW_quiz_FileUpload($question); break; case 'truefalse': $quObj = new WPCW_quiz_TrueFalse($question); break; // Not expecting anything here... so not handling the error case. // Not expecting anything here... so not handling the error case. default: break; } // Use the objects to render the questions, showing an answer as wrong if appropriate. $showAsError = false; // Only worry about errors if actual data has been submitted. $errorToShow = false; if (isset($_POST['submit'])) { // Something went wrong if (isset($resultsList['error_answer_list'][$question->question_id])) { $errorToShow = $resultsList['error_answer_list'][$question->question_id]; $showAsError = 'error'; } else { if (!isset($resultsList['answer_list'][$question->question_id])) { $showAsError = 'missing'; } else { if (isset($resultsList['wrong_answer_list'][$question->question_id])) { $showAsError = 'wrong'; } } } } // Use object to render $html .= $quObj->renderForm_toString($quizDetails, $questionNum++, $selectAnswer, $showAsError, $errorToShow); } } // #### 4 - The submit answers button. //<a href="#" class="fe_btn fe_btn_completion btn_completion" id="quiz_complete_%d_%d">%s</a> $html .= sprintf('<div class="wpcw_fe_quiz_submit"> <div class="wpcw_fe_upload_progress"> <div class="wpcw_fe_upload_progress_bar"></div> <div class="wpcw_fe_upload_progress_percent">0%%</div> </div> <div class="wpcw_fe_submit_loader wpcw_loader"> <img src="%simg/ajax_loader.gif" /> </div> <input type="submit" class="fe_btn fe_btn_completion btn_completion" name="submit" value="%s"> </div>', WPCW_plugin_getPluginPath(), __('Submit Answers', 'wp_courseware')); $html .= '</div>'; // .wpcw_fe_quiz_box $html .= '</form>'; $html .= '</div>'; // .wpcw_fe_quiz_box_wrap return $html; }
/** * Function to show a list of questions in the question pool for use by a standard page or the AJAX thickbox. * * @param Integer $itemsPerPage The number of items to show on each table page. * @param Array $paramSrc The array of parameters to use for filtering/searching the question pool. * @param String $actionMode The type of mode we're in (ajax or std). * @param PageBuilder $page The current page object (optional). */ function WPCW_questionPool_showPoolTable($itemsPerPage, $paramSrc, $actionMode = 'std', $page = false) { global $wpcwdb, $wpdb; $wpdb->show_errors(); // AJAX loader if ('ajax' == $actionMode) { printf('<img src="%simg/ajax_loader.gif" class="wpcw_loader" style="display: none;" />', WPCW_plugin_getPluginPath()); } // Check to see if we've got questions to process if ('std' == $actionMode) { WPCW_showPage_QuestionPool_processActionForm($page); } $paging_pageWanted = WPCW_arrays_getValue($paramSrc, 'pagenum') + 0; if ($paging_pageWanted == 0) { $paging_pageWanted = 1; } // Handle the sorting and filtering $orderBy = WPCW_arrays_getValue($paramSrc, 'orderby'); $ordering = WPCW_arrays_getValue($paramSrc, 'order'); // Validate ordering switch ($orderBy) { case 'question_question': case 'question_type': break; // Default and question_id //case 'question_id': // Default and question_id //case 'question_id': default: $orderBy = 'qs.question_id'; break; } // Create opposite ordering for reversing it. $ordering_opposite = false; switch ($ordering) { case 'desc': $ordering_opposite = 'asc'; break; case 'asc': $ordering_opposite = 'desc'; break; default: $ordering = 'desc'; $ordering_opposite = 'asc'; break; } // Was a search string specified? Or a specific item? $searchString = WPCW_arrays_getValue($paramSrc, 's'); // Create WHERE string based search - Title or Description of Quiz $SQL_WHERE = false; if ($searchString) { $SQL_WHERE = $wpdb->prepare(" AND question_question LIKE %s", '%' . $searchString . '%'); } $summaryPageURL = admin_url('admin.php?page=WPCW_showPage_QuestionPool'); // Show the form for searching ?> <form id="wpcw_questions_search_box" method="get" action="<?php echo $summaryPageURL; ?> "> <p class="search-box"> <label class="screen-reader-text" for="wpcw_questions_search_input"><?php _e('Search Questions', 'wp_courseware'); ?> </label> <input id="wpcw_questions_search_input" type="text" value="<?php echo $searchString; ?> " name="s"/> <input class="button" type="submit" value="<?php _e('Search Questions', 'wp_courseware'); ?> "/> <input type="hidden" name="page" value="WPCW_showPage_QuestionPool" /> </p> </form> <?php $SQL_TAG_FILTER = false; $tagFilter = intval(WPCW_arrays_getValue($paramSrc, 'filter', false)); // See if we have any tag filtering to do. if ($tagFilter > 0) { // Ensure we add the tag mapping table to the query $SQL_TAG_FILTER = "\n\t\t\tLEFT JOIN {$wpcwdb->question_tag_mapping} qtm ON qtm.question_id = qs.question_id\t\n\t\t"; $SQL_WHERE .= $wpdb->prepare("\n\t\t\tAND qtm.tag_id = %d\n\t\t\tAND qs.question_question IS NOT NULL \n\t\t", $tagFilter); // } $SQL_PAGING = "\n\t\t\tSELECT COUNT(*) as question_count \n\t\t\tFROM {$wpcwdb->quiz_qs} qs\n\t\t\t{$SQL_TAG_FILTER}\n\t\t\tWHERE question_type <> 'random_selection'\n\t\t\t{$SQL_WHERE} \n\t\t"; $paging_resultsPerPage = $itemsPerPage; $paging_totalCount = $wpdb->get_var($SQL_PAGING); $paging_recordStart = ($paging_pageWanted - 1) * $paging_resultsPerPage + 1; $paging_recordEnd = $paging_pageWanted * $paging_resultsPerPage; $paging_pageCount = ceil($paging_totalCount / $paging_resultsPerPage); $paging_sqlStart = $paging_recordStart - 1; // Show search message - that a search has been tried. if ($searchString) { printf('<div class="wpcw_search_count">%s "%s" (%s %s) (<a href="%s">%s</a>)</div>', __('Search results for', 'wp_courseware'), htmlentities($searchString), $paging_totalCount, _n('result', 'results', $paging_totalCount, 'wp_courseware'), $summaryPageURL, __('reset', 'wp_courseware')); } // Do main query $SQL = "SELECT * \n\t\t\tFROM {$wpcwdb->quiz_qs} qs\t\t\t\n\t\t\t{$SQL_TAG_FILTER}\t\t\t\n\t\t\tWHERE question_type <> 'random_selection'\n\t\t\t{$SQL_WHERE}\n\t\t\tORDER BY {$orderBy} {$ordering}\n\t\t\tLIMIT {$paging_sqlStart}, {$paging_resultsPerPage}\t\t\t \n\t\t\t"; // These are already checked, so they are safe, hence no prepare() // Generate paging code $baseURL = WPCW_urls_getURLWithParams($summaryPageURL, 'pagenum') . "&pagenum="; $questions = $wpdb->get_results($SQL); $tbl = new TableBuilder(); $tbl->attributes = array('id' => 'wpcw_tbl_question_pool', 'class' => 'widefat wpcw_tbl'); // Checkbox Col //$tblCol = new TableColumn(false, 'question_selection'); //$tblCol->cellClass = "question_selection wpcw_center"; //$tbl->addColumn($tblCol); // Wanting sorting links... in standard mode if ('std' == $actionMode) { // Checkbox field (no name, as we'll use jQuery to do a check all) $tblCol = new TableColumn('<input type="checkbox" />', 'question_id_cb'); $tblCol->cellClass = "wpcw_center wpcw_select_cb"; $tblCol->headerClass = "wpcw_center wpcw_select_cb"; $tbl->addColumn($tblCol); // ID - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=question_id"><span>%s</span><span class="sorting-indicator"></span></a>', $baseURL, 'question_id' == $orderBy ? $ordering_opposite : 'asc', __('ID', 'wp_courseware')); // ID - render $tblCol = new TableColumn($sortableLink, 'question_id'); $tblCol->headerClass = 'question_id' == $orderBy ? 'sorted ' . $ordering : 'sortable'; $tblCol->cellClass = "question_id"; $tbl->addColumn($tblCol); // Question - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=question_question"><span>%s</span><span class="sorting-indicator"></span></a>', $baseURL, 'question_question' == $orderBy ? $ordering_opposite : 'asc', __('Question', 'wp_courseware')); // Question - render $tblCol = new TableColumn($sortableLink, 'question_question'); $tblCol->headerClass = 'question_question' == $orderBy ? 'sorted ' . $ordering : 'sortable'; $tblCol->cellClass = "question_question"; $tbl->addColumn($tblCol); // Question Type - sortable $sortableLink = sprintf('<a href="%s&order=%s&orderby=question_type"><span>%s</span><span class="sorting-indicator"></span></a>', $baseURL, 'question_type' == $orderBy ? $ordering_opposite : 'asc', __('Question Type', 'wp_courseware')); // Question Type - render $tblCol = new TableColumn($sortableLink, 'question_type'); $tblCol->headerClass = ('question_type' == $orderBy ? 'sorted ' . $ordering : 'sortable') . ' wpcw_center'; $tblCol->cellClass = "question_type"; $tbl->addColumn($tblCol); } else { $tblCol = new TableColumn(__('ID', 'wp_courseware'), 'question_id'); $tblCol->cellClass = "question_id"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Question', 'wp_courseware'), 'question_question'); $tblCol->cellClass = "question_question"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Question Type', 'wp_courseware'), 'question_type'); $tblCol->cellClass = "question_type"; $tbl->addColumn($tblCol); } $tblCol = new TableColumn(__('Associated Quizzes', 'wp_courseware'), 'associated_quizzes'); $tblCol->headerClass = "wpcw_center"; $tblCol->cellClass = "associated_quizzes wpcw_center"; $tbl->addColumn($tblCol); $tblCol = new TableColumn(__('Tags', 'wp_courseware'), 'question_tags'); $tblCol->cellClass = "question_tags wpcw_center"; $tbl->addColumn($tblCol); // Actions $tblCol = new TableColumn(__('Actions', 'wp_courseware'), 'actions'); $tblCol->cellClass = "actions actions_right"; $tblCol->headerClass = "actions_right"; $tbl->addColumn($tblCol); // Stores course details in a mini cache to save lots of MySQL lookups. $miniCourseDetailCache = array(); // Format row data and show it. if ($questions) { $odd = false; foreach ($questions as $singleQuestion) { $data = array(); // URLs $editURL = admin_url('admin.php?page=WPCW_showPage_ModifyQuestion&question_id=' . $singleQuestion->question_id); // Maintain paging where possible. $deleteURL = $baseURL . '&action=delete&question_id=' . $singleQuestion->question_id; // Basic Details $data['question_id'] = $singleQuestion->question_id; $data['question_type'] = WPCW_quizzes_getQuestionTypeName($singleQuestion->question_type); $data['question_id_cb'] = sprintf('<input type="checkbox" name="question_%d" />', $singleQuestion->question_id); // Association Count $data['associated_quizzes'] = $singleQuestion->question_usage_count; // Actions - Std mode if ('std' == $actionMode) { // Edit by clicking $data['question_question'] = sprintf('<a href="%s">%s</a>', $editURL, $singleQuestion->question_question); $data['actions'] = '<ul class="wpcw_action_link_list">'; $data['actions'] .= sprintf('<li><a href="%s" class="button-primary">%s</a></li>', $editURL, __('Edit', 'wp_courseware')); $data['actions'] .= sprintf('<li><a href="%s" class="button-secondary wpcw_action_link_delete_question wpcw_action_link_delete" rel="%s">%s</a></li>', $deleteURL, __('Are you sure you wish to delete this question? This cannot be undone.', 'wp_courseware'), __('Delete', 'wp_courseware')); $data['actions'] .= '</ul>'; } else { if ('ajax' == $actionMode) { // No Edit by clicking $data['question_question'] = $singleQuestion->question_question . sprintf('<span class="wpcw_action_status wpcw_action_status_added">%s</span>', __('Added', 'wp_courseware')); $data['actions'] = '<ul class="wpcw_action_link_list">'; $data['actions'] .= sprintf('<li><a href="#" class="button-primary wpcw_tb_action_add" data-questionnum="%d">%s</a></li>', $singleQuestion->question_id, __('Add To Quiz', 'wp_courseware')); $data['actions'] .= '</ul>'; } } // Tags $data['question_tags'] = sprintf('<span class="wpcw_quiz_details_question_tags" data-questionid="%d" id="wpcw_quiz_details_question_tags_%d">', $singleQuestion->question_id, $singleQuestion->question_id); $data['question_tags'] .= WPCW_questions_tags_render($singleQuestion->question_id, WPCW_questions_tags_getTagsForQuestion($singleQuestion->question_id)); $data['question_tags'] .= '</span>'; // Odd/Even row colouring. $odd = !$odd; $tbl->addRow($data, $odd ? 'alternate' : ''); } } else { // No questions - show error in table. $tbl->addRowObj(new RowDataSimple('wpcw_center wpcw_none_found', __('There are currently no questions to show.', 'wp_courseware'), 7)); } // Add the form for the start of the multiple-add $formWrapper_start = false; if ('std' == $actionMode) { // Set the action URL to preserve parameters that we have. $formWrapper_start = sprintf('<form method="POST" action="%s">', WPCW_urls_getURLWithParams($summaryPageURL, 'pagenum')); } // Create tag filter (uses a form) $tagFilter = WPCW_questions_tags_createTagFilter($tagFilter, 'WPCW_showPage_QuestionPool'); // Work out paging and filtering $paging = WPCW_tables_showPagination($baseURL, $paging_pageWanted, $paging_pageCount, $paging_totalCount, $paging_recordStart, $paging_recordEnd, $tagFilter); // Show the actions $formWrapper_end = false; if ('std' == $actionMode) { $formWrapper_end = WPCW_showPage_QuestionPool_actionForm(); // Form tag - needed for processing $formWrapper_end .= '</form>'; } // Finally show table return $paging . $formWrapper_start . $tbl->toString() . $formWrapper_end . $paging; }