| 1 |
<?php |
| 2 |
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly |
| 3 |
|
| 4 |
function watu_exams() { |
| 5 |
global $wpdb; |
| 6 |
$quiz_id = empty($_REQUEST['quiz']) ? 0 : intval($_REQUEST['quiz']); |
| 7 |
|
| 8 |
if( isset($_REQUEST['message']) && $_REQUEST['message'] == 'updated') print '<div id="message" class="updated fade"><p>' . __('Test updated', 'watu') . '</p></div>'; |
| 9 |
if(isset($_REQUEST['message']) && $_REQUEST['message'] == 'fail') print '<div id="message" class="updated error"><p>' . __('Error occured', 'watu') . '</p></div>'; |
| 10 |
if( isset($_REQUEST['grade']) ) { |
| 11 |
$_REQUEST['grade'] = esc_html($_REQUEST['grade']); |
| 12 |
print '<div id="message" class="updated fade"><p>' . $_REQUEST['grade']. '</p></div>'; |
| 13 |
} |
| 14 |
|
| 15 |
if(!empty($_GET['action']) and $_GET['action'] == 'delete' and check_admin_referer('watu_exams')) { |
| 16 |
$wpdb->get_results($wpdb->prepare("DELETE FROM ".WATU_EXAMS." WHERE ID=%d", $quiz_id)); |
| 17 |
$wpdb->get_results($wpdb->prepare("DELETE FROM ".WATU_ANSWERS." WHERE question_id IN (SELECT ID FROM ".WATU_QUESTIONS." WHERE exam_id=%d)", $quiz_id)); |
| 18 |
$wpdb->get_results($wpdb->prepare("DELETE FROM ".WATU_QUESTIONS." WHERE exam_id=%d", $quiz_id)); |
| 19 |
print '<div id="message" class="updated fade"><p>' . __('Test deleted', 'watu') . '</p></div>'; |
| 20 |
} |
| 21 |
|
| 22 |
$allowed_columns = array( |
| 23 |
'Q.ID', |
| 24 |
'Q.name', |
| 25 |
'Q.added_on', |
| 26 |
'question_count', |
| 27 |
'taken' |
| 28 |
); |
| 29 |
|
| 30 |
$ob = isset($_GET['ob']) && in_array($_GET['ob'], $allowed_columns) ? $_GET['ob'] : 'Q.ID'; |
| 31 |
|
| 32 |
$dir = empty($_GET['dir']) ? "DESC" : $_GET['dir']; |
| 33 |
if($dir != 'DESC' and $dir != 'ASC') $dir = 'ASC'; |
| 34 |
$odir = ($dir == 'ASC') ? 'DESC' : 'ASC'; |
| 35 |
$offset = empty($_GET['offset']) ? 0 : intval($_GET['offset']); |
| 36 |
$page_limit = 10; |
| 37 |
|
| 38 |
$filter_sql = $filter_params = ''; |
| 39 |
|
| 40 |
if(!empty($_GET['title'])) { |
| 41 |
$get_title = sanitize_text_field($_GET['title']); |
| 42 |
$filter_sql .= $wpdb->prepare(" AND Q.name LIKE %s ", '%'.$wpdb->esc_like($get_title).'%'); |
| 43 |
$filter_params .= "&title=".esc_attr($get_title); |
| 44 |
} |
| 45 |
|
| 46 |
if(!empty($_GET['exam_id'])) { |
| 47 |
$filter_sql .= $wpdb->prepare(" AND Q.ID = %d ", intval($_GET['exam_id'])); |
| 48 |
$filter_params .= "&exam_id=".intval($_GET['exam_id']); |
| 49 |
} |
| 50 |
|
| 51 |
// Retrieve the quizzes |
| 52 |
$exams = $wpdb->get_results("SELECT SQL_CALC_FOUND_ROWS Q.ID,Q.name,Q.added_on, |
| 53 |
(SELECT COUNT(ID) FROM ".WATU_QUESTIONS." WHERE exam_id=Q.ID) AS question_count, |
| 54 |
(SELECT COUNT(ID) FROM ".WATU_TAKINGS." WHERE exam_id=Q.ID) AS taken |
| 55 |
FROM `".WATU_EXAMS."` AS Q |
| 56 |
WHERE ID > 0 $filter_sql |
| 57 |
ORDER BY $ob $dir LIMIT $offset, $page_limit"); |
| 58 |
|
| 59 |
$count = $wpdb->get_var("SELECT FOUND_ROWS()"); |
| 60 |
|
| 61 |
// now select all posts that have watu shortcode in them |
| 62 |
$posts=$wpdb->get_results("SELECT * FROM {$wpdb->prefix}posts |
| 63 |
WHERE post_content LIKE '%[WATU %]%' |
| 64 |
AND post_status='publish' AND post_title!='' |
| 65 |
ORDER BY post_date DESC"); |
| 66 |
|
| 67 |
// match posts to exams |
| 68 |
foreach($exams as $cnt=>$exam) { |
| 69 |
foreach($posts as $post) { |
| 70 |
if(strstr($post->post_content,"[WATU ".$exam->ID."]")) { |
| 71 |
$exams[$cnt]->post=$post; |
| 72 |
break; |
| 73 |
} |
| 74 |
} |
| 75 |
} |
| 76 |
if(@file_exists(get_stylesheet_directory().'/watu/exams.html.php')) include get_stylesheet_directory().'/watu/exams.html.php'; |
| 77 |
else include(WATU_PATH . '/views/exams.html.php'); |
| 78 |
} |
| 79 |
|
| 80 |
function watu_exam() { |
| 81 |
global $wpdb, $user_ID; |
| 82 |
$answer_display = get_option('watu_show_answers'); |
| 83 |
|
| 84 |
if(isset($_POST['submit']) and check_admin_referer('watu_create_edit_quiz')) { |
| 85 |
// use email output? |
| 86 |
$email_output = empty($_POST['different_email_output']) ? '' : wp_kses_post($_POST['email_output']); |
| 87 |
|
| 88 |
$name = sanitize_text_field($_POST['name']); |
| 89 |
$randomize = empty($_POST['randomize']) ? 0 : 1; |
| 90 |
$single_page = empty($_POST['single_page']) ? 0 : 1; |
| 91 |
$show_answers = empty($_POST['show_answers']) ? 0 : intval($_POST['show_answers']); |
| 92 |
$show_answers = empty($_POST['show_answers']) ? 0 : intval($_POST['show_answers']); |
| 93 |
$require_login = empty($_POST['require_login']) ? 0 : 1; |
| 94 |
$notify_admin = empty($_POST['notify_admin']) ? 0 : 1; |
| 95 |
$randomize_answers = empty($_POST['randomize_answers']) ? 0 : 1; |
| 96 |
$pull_random = intval($_POST['pull_random']); |
| 97 |
$dont_store_data = empty($_POST['dont_store_data']) ? 0 : 1; |
| 98 |
$show_prev_button = empty($_POST['show_prev_button']) ? 0 : 1; |
| 99 |
$dont_display_question_numbers = empty($_POST['dont_display_question_numbers']) ? 0 : 1; |
| 100 |
$require_text_captcha = empty($_POST['require_text_captcha']) ? 0 : 1; |
| 101 |
$notify_user = empty($_POST['notify_user']) ? 0 : 1; |
| 102 |
$notify_email = sanitize_text_field($_POST['notify_email']); |
| 103 |
$email_subject = sanitize_text_field($_POST['email_subject']); |
| 104 |
$take_again = empty($_POST['take_again']) ? 0 : 1; |
| 105 |
$times_to_take = intval($_POST['times_to_take']); |
| 106 |
$quiz_id = intval($_POST['quiz']); |
| 107 |
$description = watu_strip_tags($_POST['description']); |
| 108 |
$content = watu_strip_tags($_POST['content']); |
| 109 |
$no_alert_unanswered = empty($_POST['no_alert_unanswered']) ? 0 : 1; |
| 110 |
$use_honeypot = empty($_POST['use_honeypot']) ? 0 : 1; |
| 111 |
$save_source_url = empty($_POST['save_source_url']) ? 0 : 1; |
| 112 |
$advanced_settings = array(); |
| 113 |
$advanced_settings['submit_button_value'] = empty($_POST['submit_button_value']) ? __('Submit', 'watu') : sanitize_text_field($_POST['submit_button_value']); |
| 114 |
$advanced_settings['transfer_moola'] = empty($_POST['transfer_moola']) ? 0 : 1; |
| 115 |
$advanced_settings['transfer_moola_mode'] = empty($_POST['transfer_moola_mode']) ? '' : sanitize_text_field($_POST['transfer_moola_mode']); |
| 116 |
$advanced_settings['design_theme'] = sanitize_text_field($_POST['design_theme']); |
| 117 |
$advanced_settings['total_attempts_limit'] = empty($_POST['total_attempts_limit']) ? 0 : intval($_POST['total_attempts_limit']); |
| 118 |
$advanced_settings['total_attempts_limit_message'] = empty($_POST['total_attempts_limit_message']) ? '' : rawurlencode(sanitize_text_field($_POST['total_attempts_limit_message'])); |
| 119 |
$advanced_settings = serialize($advanced_settings); |
| 120 |
$is_scheduled = empty($_POST['is_scheduled']) ? 0 : 1; |
| 121 |
$schedule_from = empty($_POST['schedule_from']) ? date('Y-m-d') : sanitize_text_field($_POST['schedule_from']); |
| 122 |
$schedule_to = empty($_POST['schedule_to']) ? date('Y-m-d') : sanitize_text_field($_POST['schedule_to']); |
| 123 |
$schedule_from = $schedule_from.' '.sprintf('%02d', $_POST['schedule_from_hour']).':'.sprintf('%02d', $_POST['schedule_from_minute']).':00'; |
| 124 |
$schedule_to = $schedule_to.' '.sprintf('%02d', $_POST['schedule_to_hour']).':'.sprintf('%02d', $_POST['schedule_to_minute']).':00'; |
| 125 |
|
| 126 |
if($_REQUEST['action'] == 'edit') { //Update goes here |
| 127 |
$exam_id = $_REQUEST['quiz']; |
| 128 |
$wpdb->query($wpdb->prepare("UPDATE ".WATU_EXAMS." |
| 129 |
SET name=%s, description=%s,final_screen=%s, randomize=%d, single_page=%d, |
| 130 |
show_answers=%d, require_login=%d, notify_admin=%d, randomize_answers=%d, |
| 131 |
pull_random=%d, dont_store_data=%d, show_prev_button=%d, |
| 132 |
dont_display_question_numbers=%d, require_text_captcha=%d, email_output=%s, |
| 133 |
notify_user=%d, notify_email=%s, take_again=%d, times_to_take=%d, no_alert_unanswered=%d, |
| 134 |
use_honeypot=%d, save_source_url=%d, advanced_settings = %s, email_subject=%s, |
| 135 |
is_scheduled=%d, schedule_from=%s, schedule_to=%s |
| 136 |
WHERE ID=%d", $name, $description, $content, |
| 137 |
$randomize, $single_page, $show_answers, |
| 138 |
$require_login, $notify_admin, $randomize_answers, |
| 139 |
$pull_random, $dont_store_data, $show_prev_button, |
| 140 |
$dont_display_question_numbers, $require_text_captcha, |
| 141 |
$email_output, $notify_user, $notify_email, |
| 142 |
$take_again, $times_to_take, $no_alert_unanswered, $use_honeypot, $save_source_url, |
| 143 |
$advanced_settings, $email_subject, $is_scheduled, $schedule_from, $schedule_to, $quiz_id)); |
| 144 |
|
| 145 |
if(!empty($_POST['auto_publish'])) watu_auto_publish($exam_id); |
| 146 |
$wp_redirect = 'admin.php?page=watu_exams&message=updated'; |
| 147 |
|
| 148 |
} else { |
| 149 |
$no_ajax = 0; |
| 150 |
if(get_option('watu_no_ajax') == 1) $no_ajax = 1; |
| 151 |
|
| 152 |
$wpdb->query($wpdb->prepare("INSERT INTO ".WATU_EXAMS." |
| 153 |
(name, description, final_screen, added_on, randomize, single_page, show_answers, require_login, |
| 154 |
notify_admin, randomize_answers, pull_random, dont_store_data, show_prev_button, |
| 155 |
dont_display_question_numbers, require_text_captcha, email_output, notify_user, |
| 156 |
notify_email, take_again, times_to_take, no_alert_unanswered, use_honeypot, save_source_url, |
| 157 |
advanced_settings, email_subject, no_ajax, is_scheduled, schedule_from, schedule_to) |
| 158 |
VALUES(%s, %s, %s, NOW(), %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %s, %d, %s, %d, %d, %d, %d, %d, %s, %s, %d, |
| 159 |
%d, %s, %s)", |
| 160 |
$name, $description, $content, $randomize, $single_page, |
| 161 |
$show_answers, $require_login, $notify_admin, |
| 162 |
$randomize_answers, $pull_random, $dont_store_data, |
| 163 |
$show_prev_button, $dont_display_question_numbers, |
| 164 |
$require_text_captcha, $email_output, $notify_user, |
| 165 |
$notify_email, $take_again, $times_to_take, $no_alert_unanswered, $use_honeypot, $save_source_url, |
| 166 |
$advanced_settings, $email_subject, $no_ajax, $is_scheduled, $schedule_from, $schedule_to)); |
| 167 |
$exam_id = $wpdb->insert_id; |
| 168 |
if(!empty($_POST['auto_publish'])) watu_auto_publish($exam_id); |
| 169 |
if($exam_id == 0 ) $wp_redirect = 'admin.php?page=watu_exams&message=fail'; |
| 170 |
$wp_redirect = 'admin.php?page=watu_questions&message=new_quiz&quiz='.$exam_id; |
| 171 |
} |
| 172 |
|
| 173 |
$wp_redirect = admin_url($wp_redirect); |
| 174 |
|
| 175 |
do_action('watu_exam_saved', $exam_id); |
| 176 |
|
| 177 |
echo "<meta http-equiv='refresh' content='0;url=$wp_redirect' />"; |
| 178 |
exit; |
| 179 |
} |
| 180 |
|
| 181 |
|
| 182 |
$action = 'new'; |
| 183 |
if(!empty($_REQUEST['action']) and $_REQUEST['action'] == 'edit') $action = 'edit'; |
| 184 |
|
| 185 |
$dquiz = array(); |
| 186 |
$grades = array(); |
| 187 |
if($action == 'edit') { |
| 188 |
$dquiz = $wpdb->get_row($wpdb->prepare("SELECT * FROM ".WATU_EXAMS." WHERE ID=%d", intval($_REQUEST['quiz']))); |
| 189 |
$grades = $wpdb->get_results($wpdb->prepare("SELECT * FROM ".WATU_GRADES." WHERE exam_id=%d order by ID ", intval($_REQUEST['quiz'])) ); |
| 190 |
$final_screen = stripslashes($dquiz->final_screen); |
| 191 |
|
| 192 |
$schedule_from = $dquiz->schedule_from; |
| 193 |
list($schedule_from) = explode(" ", $schedule_from); |
| 194 |
$schedule_to = $dquiz->schedule_to; |
| 195 |
list($schedule_to) = explode(" ", $schedule_to); |
| 196 |
} else { |
| 197 |
$final_screen = __("<p>Congratulations - you have completed %%QUIZ_NAME%%.</p>\n\n<p>You scored %%POINTS%% points out of %%MAX-POINTS%% points total.</p>\n\n<p>Your obtained grade is <b>%%GRADE-TITLE%%</b></p><p>%%GRADE-DESCRIPTION%%</p>\n\n<p>Your answers are shown below:<p>%%ANSWERS%%", 'watu'); |
| 198 |
$schedule_from = date("Y-m-d"); |
| 199 |
$schedule_to = date("Y-m-d"); |
| 200 |
} |
| 201 |
|
| 202 |
// see what is the show_answers to this exam |
| 203 |
if(!isset($dquiz->show_answers) or $dquiz->show_answers == 100) $answer_display = $answer_display; // assign the default |
| 204 |
else $answer_display = $dquiz->show_answers; |
| 205 |
|
| 206 |
if(!empty($_GET['quiz'])) { |
| 207 |
$quiz_id = intval($_GET['quiz']); |
| 208 |
$is_published = $wpdb->get_var("SELECT ID FROM {$wpdb->posts} WHERE post_content LIKE '%[watu ".$quiz_id."]%' |
| 209 |
AND post_status='publish' AND post_title!=''"); |
| 210 |
$advanced_settings = unserialize(stripslashes($dquiz->advanced_settings)); |
| 211 |
} |
| 212 |
else $is_published = false; |
| 213 |
|
| 214 |
watu_enqueue_datepicker(); |
| 215 |
if(@file_exists(get_stylesheet_directory().'/watu/exam_form.php')) include get_stylesheet_directory().'/watu/exam_form.php'; |
| 216 |
else include(WATU_PATH . '/views/exam_form.php'); |
| 217 |
} |
| 218 |
|
| 219 |
// auto publish quiz in post |
| 220 |
// some data comes directly from the $_POST to save unnecessary DB query |
| 221 |
function watu_auto_publish($quiz_id) { |
| 222 |
$post = array('post_content' => '[WATU '.$quiz_id.']', 'post_name'=> $_POST['name'], |
| 223 |
'post_title'=>$_POST['name'], 'post_status'=>'publish'); |
| 224 |
wp_insert_post($post); |
| 225 |
} |
| 226 |
|
| 227 |
// helper to check the schedle. Same called in show_exam.php |
| 228 |
function watu_check_schedule($schedule_from, $schedule_to) { |
| 229 |
$now = current_time('timestamp'); |
| 230 |
if ($now < $schedule_from or $now > $schedule_to) { |
| 231 |
// "will be" or "was" |
| 232 |
if($now > $schedule_to) $time_msg = __('was', 'watu'); |
| 233 |
else $time_msg = __('will be', 'watu'); |
| 234 |
|
| 235 |
printf(__('This %1$s %2$s available between %3$s and %4$s.', 'watu'), WATU_QUIZ_WORD, $time_msg, date_i18n(get_option('date_format').' '.get_option('time_format'), $schedule_from), date_i18n(get_option('date_format').' '.get_option('time_format'), $schedule_to)); |
| 236 |
if(current_user_can('watu_manage') or current_user_can('manage_options')) echo ' '.__('You can still see it only because you are an administrator or a manager.', 'watu').' '; |
| 237 |
else return false; // students can't take this test |
| 238 |
} |
| 239 |
return true; |
| 240 |
} |
| 241 |
|