PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 1.4.2
Tutor LMS – eLearning and online course solution v1.4.2
3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / classes / Quiz.php
tutor / classes Last commit date
Addons.php 6 years ago Admin.php 6 years ago Ajax.php 6 years ago Assets.php 6 years ago Course.php 6 years ago Course_Settings_Tabs.php 6 years ago Course_Widget.php 6 years ago Dashboard.php 6 years ago Gutenberg.php 6 years ago Instructor.php 6 years ago Instructors_List.php 6 years ago Lesson.php 6 years ago Options.php 6 years ago Post_types.php 6 years ago Q_and_A.php 6 years ago Question.php 6 years ago Question_Answers_List.php 6 years ago Quiz.php 6 years ago Quiz_Attempts_List.php 6 years ago Rewrite_Rules.php 6 years ago Shortcode.php 6 years ago Student.php 6 years ago Students_List.php 6 years ago Taxonomies.php 6 years ago Template.php 6 years ago Theme_Compatibility.php 6 years ago Tools.php 6 years ago Tutor.php 6 years ago TutorEDD.php 6 years ago Tutor_Base.php 6 years ago Tutor_List_Table.php 6 years ago Upgrader.php 6 years ago User.php 6 years ago Utils.php 6 years ago Video_Stream.php 6 years ago Withdraw.php 6 years ago Withdraw_Requests_List.php 6 years ago WooCommerce.php 6 years ago
Quiz.php
1129 lines
1 <?php
2
3 /**
4 * Quize class
5 *
6 * @author: themeum
7 * @author_uri: https://themeum.com
8 * @package Tutor
9 * @since v.1.0.0
10 */
11
12 namespace TUTOR;
13
14 if ( ! defined( 'ABSPATH' ) )
15 exit;
16
17 class Quiz {
18
19 public function __construct() {
20 add_filter( "manage_tutor_quiz_posts_columns", array($this, 'add_column'), 10,1 );
21 add_action( "manage_tutor_quiz_posts_custom_column" , array($this, 'custom_question_column'), 10, 2 );
22
23 add_action( 'add_meta_boxes', array($this, 'register_meta_box') );
24 add_action('save_post_tutor_quiz', array($this, 'save_quiz_meta'));
25
26 //Depricated at alpha version
27 add_action('wp_ajax_tutor_load_quiz_modal', array($this, 'tutor_load_quiz_modal'));
28
29 add_action('wp_ajax_tutor_load_quiz_builder_modal', array($this, 'tutor_load_quiz_builder_modal'));
30 add_action('wp_ajax_tutor_add_quiz_to_post', array($this, 'tutor_add_quiz_to_post'));
31 add_action('wp_ajax_remove_quiz_from_post', array($this, 'remove_quiz_from_post'));
32
33 add_action('wp_ajax_tutor_quiz_timeout', array($this, 'tutor_quiz_timeout'));
34
35 //User take the quiz
36 add_action('template_redirect', array($this, 'start_the_quiz'));
37 add_action('template_redirect', array($this, 'answering_quiz'));
38 add_action('template_redirect', array($this, 'finishing_quiz_attempt'));
39
40 add_action('admin_action_review_quiz_answer', array($this, 'review_quiz_answer'));
41 add_action('wp_ajax_review_quiz_answer', array($this, 'review_quiz_answer'));
42
43 /**
44 * New Design Quiz
45 */
46
47 add_action('wp_ajax_tutor_create_quiz_and_load_modal', array($this, 'tutor_create_quiz_and_load_modal'));
48 add_action('wp_ajax_tutor_delete_quiz_by_id', array($this, 'tutor_delete_quiz_by_id'));
49 add_action('wp_ajax_tutor_quiz_builder_quiz_update', array($this, 'tutor_quiz_builder_quiz_update'));
50 add_action('wp_ajax_tutor_load_edit_quiz_modal', array($this, 'tutor_load_edit_quiz_modal'));
51 add_action('wp_ajax_tutor_quiz_builder_get_question_form', array($this, 'tutor_quiz_builder_get_question_form'));
52 add_action('wp_ajax_tutor_quiz_modal_update_question', array($this, 'tutor_quiz_modal_update_question'));
53 add_action('wp_ajax_tutor_quiz_builder_question_delete', array($this, 'tutor_quiz_builder_question_delete'));
54 add_action('wp_ajax_tutor_quiz_add_question_answers', array($this, 'tutor_quiz_add_question_answers'));
55 add_action('wp_ajax_tutor_quiz_edit_question_answer', array($this, 'tutor_quiz_edit_question_answer'));
56 add_action('wp_ajax_tutor_save_quiz_answer_options', array($this, 'tutor_save_quiz_answer_options'));
57 add_action('wp_ajax_tutor_update_quiz_answer_options', array($this, 'tutor_update_quiz_answer_options'));
58 add_action('wp_ajax_tutor_quiz_builder_get_answers_by_question', array($this, 'tutor_quiz_builder_get_answers_by_question'));
59 add_action('wp_ajax_tutor_quiz_builder_delete_answer', array($this, 'tutor_quiz_builder_delete_answer'));
60 add_action('wp_ajax_tutor_quiz_question_sorting', array($this, 'tutor_quiz_question_sorting'));
61 add_action('wp_ajax_tutor_quiz_answer_sorting', array($this, 'tutor_quiz_answer_sorting'));
62 add_action('wp_ajax_tutor_mark_answer_as_correct', array($this, 'tutor_mark_answer_as_correct'));
63 add_action('wp_ajax_tutor_quiz_modal_update_settings', array($this, 'tutor_quiz_modal_update_settings'));
64
65
66
67 /**
68 * Frontend Stuff
69 */
70
71 add_action('wp_ajax_tutor_render_quiz_content', array($this, 'tutor_render_quiz_content'));
72
73 }
74
75 public function add_column($columns){
76 $date_col = $columns['date'];
77 unset($columns['date']);
78 $columns['quiz'] = __('Course', 'tutor');
79 $columns['questions'] = __('Questions', 'tutor');
80 $columns['date'] = $date_col;
81
82 return $columns;
83 }
84
85 public function custom_question_column($column, $post_id ){
86 if ($column === 'quiz'){
87 $quiz = tutor_utils()->get_course_by_quiz($post_id);
88
89 if ($quiz){
90 echo '<a href="'.admin_url('post.php?post='.$quiz->ID.'&action=edit').'">'.get_the_title($quiz->ID).'</a>';
91 }
92 }
93
94 if ($column === 'questions'){
95 echo tutor_utils()->total_questions_for_student_by_quiz($post_id);
96 }
97 }
98
99 public function register_meta_box(){
100 add_meta_box( 'tutor-quiz-questions', __( 'Questions', 'tutor' ), array($this, 'quiz_questions'), 'tutor_quiz' );
101 add_meta_box( 'tutor-quiz-settings', __( 'Settings', 'tutor' ), array($this, 'quiz_settings'), 'tutor_quiz' );
102 }
103
104 public function quiz_questions(){
105 include tutor()->path.'views/metabox/quiz_questions.php';
106 }
107
108 public function quiz_settings(){
109 include tutor()->path.'views/metabox/quizzes.php';
110 }
111
112 public function save_quiz_meta($post_ID){
113 if (isset($_POST['quiz_option'])){
114 $quiz_option = tutor_utils()->sanitize_array($_POST['quiz_option']);
115 update_post_meta($post_ID, 'tutor_quiz_option', $quiz_option);
116 }
117 }
118
119 /**
120 * @depricated at alpha version
121 * Check tutor_load_quiz_builder_modal instead of this method
122 */
123 public function tutor_load_quiz_modal(){
124 $quiz_for_post_id = (int) sanitize_text_field($_POST['quiz_for_post_id']);
125
126 $search_terms = sanitize_text_field(tutor_utils()->avalue_dot('search_terms', $_POST));
127 $quizzes = tutor_utils()->get_unattached_quiz(array('search_term' => $search_terms));
128
129 $output = '';
130 if ($quizzes){
131 foreach ($quizzes as $quiz){
132 $output .= "<p><label><input type='checkbox' name='quiz_for[{$quiz_for_post_id}][quiz_id][]' value='{$quiz->ID}' > {$quiz->post_title} </label></p>";
133 }
134 $output .= '<p class="quiz-search-suggest-text">Search the quiz to get specific quiz</p>';
135 }else{
136 $add_question_url = admin_url('post-new.php?post_type=tutor_quiz');
137 $output .= sprintf('No quiz available right now, please %s add some quiz %s', '<a href="'.$add_question_url.'" target="_blank">', '</a>' );
138 }
139
140 ob_start();
141 ?>
142 <div class="tutor-option-field-row">
143 <div class="tutor-option-field-label">
144 <label for="">
145 <?php _e('New quiz title', 'tutor'); ?>
146 </label>
147 </div>
148 <div class="tutor-option-field">
149 <input type="text" name="quiz_title" placeholder="<?php _e('Place quiz title to create new quiz', 'tutor'); ?>" >
150 <p class="desc"><?php _e('Provide a quiz title to create a quiz from here.'); ?></p>
151 </div>
152 </div>
153
154 <?php
155 $output .= ob_get_clean();
156
157 wp_send_json_success(array('output' => $output));
158 }
159
160 /**
161 * Tutor Quiz Builder Modal
162 */
163 public function tutor_load_quiz_builder_modal(){
164 ob_start();
165 include tutor()->path.'views/modal/add_quiz.php';
166 $output = ob_get_clean();
167
168 wp_send_json_success(array('output' => $output));
169
170 }
171
172 public function tutor_add_quiz_to_post(){
173 global $wpdb;
174
175 $quiz_data = tutor_utils()->avalue_dot('quiz_for', $_POST);
176
177 $output = '';
178 $post_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('parent_post_id', $_POST)) ;
179 if ($quiz_data){
180 foreach ($quiz_data as $post_id => $quiz_ids_a);
181
182 $quiz_ids = tutor_utils()->avalue_dot('quiz_id', $quiz_ids_a);
183 foreach ($quiz_ids as $quiz_id){
184 $wpdb->update($wpdb->posts, array('post_parent' => $post_id), array('ID' => $quiz_id) );
185 }
186 }
187
188 $quiz_title = sanitize_text_field(tutor_utils()->avalue_dot('quiz_title', $_POST));
189 if ($quiz_title){
190 wp_insert_post(array(
191 'post_parent' => $post_id,
192 'post_title' => $quiz_title,
193 'post_type' => 'tutor_quiz',
194 'post_status' => 'publish',
195 ));
196 }
197
198 if ($post_id) {
199 ob_start();
200 $attached_quizzes = tutor_utils()->get_attached_quiz( $post_id );
201 if ( $attached_quizzes ) {
202 foreach ( $attached_quizzes as $attached_quiz ) {
203 ?>
204 <div id="added-quiz-id-<?php echo $attached_quiz->ID; ?>" class="added-quiz-item added-quiz-item-<?php echo $attached_quiz->ID; ?>" data-quiz-id="<?php echo $attached_quiz->ID; ?>">
205 <span class="quiz-icon"><i class="dashicons dashicons-clock"></i></span>
206 <span class="quiz-name">
207 <?php edit_post_link( $attached_quiz->post_title, null, null, $attached_quiz->ID ); ?>
208 </span>
209 <span class="quiz-control">
210 <a href="javascript:;" class="tutor-quiz-delete-btn"><i class="dashicons dashicons-trash"></i></a>
211 </span>
212 </div>
213 <?php
214 }
215 }
216 $output .= ob_get_clean();
217 }
218
219 wp_send_json_success(array('output' => $output));
220 }
221
222 public function remove_quiz_from_post(){
223 global $wpdb;
224 $quiz_id = (int) tutor_utils()->avalue_dot('quiz_id', $_POST);
225 $wpdb->update($wpdb->posts, array('post_parent' => 0), array('ID' => $quiz_id) );
226 wp_send_json_success();
227 }
228
229 /**
230 *
231 * Start Quiz from here...
232 *
233 * @since v.1.0.0
234 */
235
236 public function start_the_quiz(){
237 if ( ! isset($_POST['tutor_action']) || $_POST['tutor_action'] !== 'tutor_start_quiz' ){
238 return;
239 }
240 //Checking nonce
241 tutor_utils()->checking_nonce();
242
243 if ( ! is_user_logged_in()){
244 //TODO: need to set a view in the next version
245 die('Please sign in to do this operation');
246 }
247
248 global $wpdb;
249
250 $user_id = get_current_user_id();
251 $user = get_userdata($user_id);
252
253 $quiz_id = (int) sanitize_text_field($_POST['quiz_id']);
254
255 $quiz = get_post($quiz_id);
256 $course = tutor_utils()->get_course_by_quiz($quiz_id);
257 if ( empty($course->ID)){
258 die('There is something went wrong with course, please check if quiz attached with a course');
259 }
260
261 $date = date("Y-m-d H:i:s");
262
263 $tutor_quiz_option = (array) maybe_unserialize(get_post_meta($quiz_id, 'tutor_quiz_option', true));
264 $attempts_allowed = tutor_utils()->get_quiz_option($quiz_id, 'attempts_allowed', 0);
265
266 $time_limit = tutor_utils()->get_quiz_option($quiz_id, 'time_limit.time_value');
267 $time_limit_seconds = 0;
268 $time_type = 'seconds';
269 if ($time_limit){
270 $time_type = tutor_utils()->get_quiz_option($quiz_id, 'time_limit.time_type');
271
272 switch ($time_type){
273 case 'seconds':
274 $time_limit_seconds = $time_limit;
275 break;
276 case 'minutes':
277 $time_limit_seconds = $time_limit * 60;
278 break;
279 case 'hours':
280 $time_limit_seconds = $time_limit * 60 * 60;
281 break;
282 case 'days':
283 $time_limit_seconds = $time_limit * 60 * 60 * 24;
284 break;
285 case 'weeks':
286 $time_limit_seconds = $time_limit * 60 * 60 * 24 * 7;
287 break;
288 }
289 }
290
291 $max_question_allowed = tutor_utils()->max_questions_for_take_quiz($quiz_id);
292 $tutor_quiz_option['time_limit']['time_limit_seconds'] = $time_limit_seconds;
293
294 $attempt_data = array(
295 'course_id' => $course->ID,
296 'quiz_id' => $quiz_id,
297 'user_id' => $user_id,
298 'total_questions' => $max_question_allowed,
299 'total_answered_questions' => 0,
300 'attempt_info' => maybe_serialize($tutor_quiz_option),
301 'attempt_status' => 'attempt_started',
302 'attempt_ip' => tutor_utils()->get_ip(),
303 'attempt_started_at' => $date,
304 );
305
306 $wpdb->insert($wpdb->prefix.'tutor_quiz_attempts', $attempt_data);
307 $attempt_id = (int) $wpdb->insert_id;
308
309 wp_redirect(get_permalink($quiz_id));
310 die();
311 }
312
313 public function answering_quiz(){
314 if ( tutils()->array_get('tutor_action', $_POST) !== 'tutor_answering_quiz_question' ){
315 return;
316 }
317 //Checking nonce
318 tutor_utils()->checking_nonce();
319
320 $attempt_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('attempt_id', $_POST));
321 $attempt = tutor_utils()->get_attempt($attempt_id);
322
323 $attempt_answers = isset($_POST['attempt']) ? $_POST['attempt'] : false;
324 if ( ! is_user_logged_in()){
325 die('Please sign in to do this operation');
326 }
327
328 global $wpdb;
329 $user_id = get_current_user_id();
330
331 do_action('tutor_quiz/attempt_analysing/before', $attempt_id);
332
333 if ($attempt_answers && is_array($attempt_answers) && count($attempt_answers)){
334 foreach ($attempt_answers as $attempt_id => $attempt_answers){
335
336 /**
337 * Get total marks of all question comes
338 */
339 $question_ids = tutor_utils()->avalue_dot('quiz_question_ids', $attempt_answers);
340 if (is_array($question_ids) && count($question_ids)){
341 $question_ids_string = "'".implode("','", $question_ids)."'";
342 $total_question_marks = $wpdb->get_var("SELECT SUM(question_mark) FROM {$wpdb->prefix}tutor_quiz_questions WHERE question_id IN({$question_ids_string}) ;");
343 $wpdb->update($wpdb->prefix.'tutor_quiz_attempts', array('total_marks' =>$total_question_marks ), array('attempt_id' => $attempt_id ));
344 }
345
346 if ( ! $attempt || $user_id != $attempt->user_id){
347 die('Operation not allowed, attempt not found or permission denied');
348 }
349
350 $quiz_answers = tutor_utils()->avalue_dot('quiz_question', $attempt_answers);
351 $total_marks = 0;
352 foreach ($quiz_answers as $question_id => $answers){
353 $question = tutor_utils()->get_quiz_question_by_id($question_id);
354 $question_type = $question->question_type;
355
356 $is_answer_was_correct = false;
357 $given_answer = '';
358
359 if ($question_type === 'true_false' || $question_type === 'single_choice'){
360
361 $given_answer = $answers;
362 $is_answer_was_correct = (bool) $wpdb->get_var("SELECT is_correct FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE answer_id = {$answers} ");
363
364 }elseif ($question_type === 'multiple_choice'){
365
366 $given_answer = maybe_serialize($answers);
367 $get_original_answers = (array) $wpdb->get_col("SELECT answer_id FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question->question_id} AND belongs_question_type = '{$question_type}' AND is_correct = 1 ;");
368 if (maybe_serialize($get_original_answers) == $given_answer){
369 $is_answer_was_correct = true;
370 }
371
372 }elseif ($question_type === 'fill_in_the_blank'){
373
374 $given_answer = (array) array_map('sanitize_text_field', $answers);
375 $given_answer = maybe_serialize($given_answer);
376
377 $get_original_answer = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question->question_id} AND belongs_question_type = '{$question_type}' ;");
378 $gap_answer = (array) explode('|', $get_original_answer->answer_two_gap_match);
379
380 $gap_answer = array_map('sanitize_text_field', $gap_answer);
381 if ($given_answer == maybe_serialize($gap_answer)){
382 $is_answer_was_correct = true;
383 }
384
385 }elseif ($question_type === 'open_ended' || $question_type === 'short_answer'){
386
387 $given_answer = wp_kses_post($answers);
388
389 }elseif ($question_type === 'ordering' || $question_type === 'matching'|| $question_type === 'image_matching' ){
390
391 $given_answer = (array) array_map('sanitize_text_field', tutor_utils()->avalue_dot('answers', $answers));
392 $given_answer = maybe_serialize($given_answer);
393
394 $get_original_answers = (array) $wpdb->get_col("SELECT answer_id FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question->question_id} AND belongs_question_type = '{$question_type}' ORDER BY answer_order ASC ;");
395 $get_original_answers = array_map('sanitize_text_field', $get_original_answers);
396
397 if ($given_answer == maybe_serialize($get_original_answers)){
398 $is_answer_was_correct = true;
399 }
400
401 }elseif ($question_type === 'image_answering'){
402 echo '<pre>';
403
404 $image_inputs = tutor_utils()->avalue_dot('answer_id', $answers);
405 $image_inputs = (array) array_map('sanitize_text_field', $image_inputs);
406 $given_answer = maybe_serialize($image_inputs);
407 $is_answer_was_correct = false;
408
409 $db_answer = $wpdb->get_col("SELECT answer_title FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id = {$question_id} AND belongs_question_type =
410 'image_answering' ORDER BY answer_order asc ;");
411
412 if (is_array($db_answer) && count($db_answer)){
413 $is_answer_was_correct = (strtolower(maybe_serialize(array_values($image_inputs))) == strtolower(maybe_serialize($db_answer)) );
414 }
415 }
416
417 $question_mark = $is_answer_was_correct ? $question->question_mark : 0;
418 $total_marks += $question_mark;
419
420 $answers_data = array(
421 'user_id' => $user_id,
422 'quiz_id' => $attempt->quiz_id,
423 'question_id' => $question_id,
424 'quiz_attempt_id' => $attempt_id,
425 'given_answer' => $given_answer,
426 'question_mark' => $question->question_mark,
427 'achieved_mark' => $question_mark,
428 'minus_mark' => 0,
429 'is_correct' => $is_answer_was_correct ? 1 : 0,
430 );
431 $wpdb->insert($wpdb->prefix.'tutor_quiz_attempt_answers', $answers_data);
432 }
433
434 $attempt_info = array(
435 'total_answered_questions' => count($quiz_answers),
436 'earned_marks' => $total_marks,
437 'attempt_status' => 'attempt_ended',
438 'attempt_ended_at' => date("Y-m-d H:i:s"),
439 );
440 $wpdb->update($wpdb->prefix.'tutor_quiz_attempts', $attempt_info, array('attempt_id' => $attempt_id));
441 }
442
443 do_action('tutor_quiz/attempt_ended', $attempt_id);
444 }
445
446 wp_redirect(get_the_permalink($attempt->quiz_id));
447 die();
448 }
449
450
451 /**
452 * Quiz attempt will be finish here
453 *
454 */
455
456 public function finishing_quiz_attempt(){
457 if ( ! isset($_POST['tutor_action']) || $_POST['tutor_action'] !== 'tutor_finish_quiz_attempt' ){
458 return;
459 }
460 //Checking nonce
461 tutor_utils()->checking_nonce();
462
463 if ( ! is_user_logged_in()){
464 die('Please sign in to do this operation');
465 }
466
467 global $wpdb;
468
469 $quiz_id = (int) sanitize_text_field($_POST['quiz_id']);
470 $attempt = tutor_utils()->is_started_quiz($quiz_id);
471 $attempt_id = $attempt->attempt_id;
472
473 $attempt_info = array(
474 'total_answered_questions' => 0,
475 'earned_marks' => 0,
476 'attempt_status' => 'attempt_ended',
477 'attempt_ended_at' => date("Y-m-d H:i:s"),
478 );
479
480 do_action('tutor_quiz_before_finish', $attempt_id, $quiz_id, $attempt->user_id);
481 $wpdb->update($wpdb->prefix.'tutor_quiz_attempts', $attempt_info, array('attempt_id' => $attempt_id));
482 do_action('tutor_quiz_finished', $attempt_id, $quiz_id, $attempt->user_id);
483
484 wp_redirect(tutor_utils()->input_old('_wp_http_referer'));
485 }
486
487 /**
488 * Quiz timeout by ajax
489 */
490 public function tutor_quiz_timeout(){
491 global $wpdb;
492
493 $quiz_id = (int) sanitize_text_field($_POST['quiz_id']);
494 $attempt = tutor_utils()->is_started_quiz($quiz_id);
495
496 if ($attempt) {
497 $attempt_id = $attempt->attempt_id;
498
499 $data = array(
500 'attempt_status' => 'attempt_timeout',
501 'attempt_ended_at' => date("Y-m-d H:i:s"),
502 );
503 $wpdb->update($wpdb->prefix.'tutor_quiz_attempts', $data, array('attempt_id' => $attempt->attempt_id));
504
505 do_action('tutor_quiz_timeout', $attempt_id, $quiz_id, $attempt->user_id);
506
507 wp_send_json_success();
508 }
509
510 wp_send_json_error(__('Quiz has been timeout already', 'tutor'));
511 }
512
513 /**
514 * Review the answer and change individual answer result
515 */
516
517 public function review_quiz_answer(){
518 global $wpdb;
519 $attempt_id = (int) sanitize_text_field($_GET['attempt_id']);
520 $attempt_answer_id = (int) sanitize_text_field($_GET['attempt_answer_id']);
521 $mark_as = sanitize_text_field($_GET['mark_as']);
522
523 $attempt_answer = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_attempt_answers WHERE attempt_answer_id = {$attempt_answer_id} ");
524 $attempt = tutor_utils()->get_attempt($attempt_id);
525
526 $is_correct = (int) $attempt_answer->is_correct;
527
528 do_action('tutor_quiz_review_answer_before', $attempt_answer_id, $attempt_id, $mark_as);
529
530 if ($mark_as === 'correct' && ! $is_correct){
531
532 $answer_update_data = array(
533 'achieved_mark' => $attempt_answer->question_mark,
534 'is_correct' => 1,
535 );
536 $wpdb->update($wpdb->prefix.'tutor_quiz_attempt_answers', $answer_update_data, array('attempt_answer_id' => $attempt_answer_id ));
537
538 $attempt_update_data = array(
539 'earned_marks' => $attempt->earned_marks + $attempt_answer->question_mark,
540 'is_manually_reviewed' => 1,
541 'manually_reviewed_at' => date("Y-m-d H:i:s"),
542 );
543
544 $wpdb->update($wpdb->prefix.'tutor_quiz_attempts', $attempt_update_data, array('attempt_id' => $attempt_id ));
545
546 }elseif($mark_as === 'incorrect' && $is_correct){
547
548 $answer_update_data = array(
549 'achieved_mark' => '0.00',
550 'is_correct' => 0,
551 );
552 $wpdb->update($wpdb->prefix.'tutor_quiz_attempt_answers', $answer_update_data, array('attempt_answer_id' => $attempt_answer_id ));
553
554 $attempt_update_data = array(
555 'earned_marks' => $attempt->earned_marks - $attempt_answer->question_mark,
556 'is_manually_reviewed' => 1,
557 'manually_reviewed_at' => date("Y-m-d H:i:s"),
558 );
559
560 $wpdb->update($wpdb->prefix.'tutor_quiz_attempts', $attempt_update_data, array('attempt_id' => $attempt_id ));
561 }
562 do_action('tutor_quiz_review_answer_after', $attempt_answer_id, $attempt_id, $mark_as);
563
564 if (wp_doing_ajax()){
565 wp_send_json_success();
566 }else{
567 wp_redirect(admin_url("admin.php?page=tutor_quiz_attempts&sub_page=view_attempt&attempt_id=".$attempt_id));
568 }
569
570 die();
571 }
572
573
574 /**
575 * New Design Quiz
576 */
577 public function tutor_create_quiz_and_load_modal(){
578 $topic_id = sanitize_text_field($_POST['topic_id']);
579 $quiz_title = sanitize_text_field($_POST['quiz_title']);
580 $quiz_description = sanitize_text_field($_POST['quiz_description']);
581 $next_order_id = tutor_utils()->get_next_course_content_order_id($topic_id);
582
583 $post_arr = array(
584 'post_type' => 'tutor_quiz',
585 'post_title' => $quiz_title,
586 'post_content' => $quiz_description,
587 'post_status' => 'publish',
588 'post_author' => get_current_user_id(),
589 'post_parent' => $topic_id,
590 'menu_order' => $next_order_id,
591 );
592 $quiz_id = wp_insert_post( $post_arr );
593 do_action('tutor_initial_quiz_created', $quiz_id);
594
595 ob_start();
596 include tutor()->path.'views/modal/edit_quiz.php';
597 $output = ob_get_clean();
598
599 ob_start();
600 ?>
601 <div id="tutor-quiz-<?php echo $quiz_id; ?>" class="course-content-item tutor-quiz tutor-quiz-<?php echo $quiz_id; ?>">
602 <div class="tutor-lesson-top">
603 <i class="tutor-icon-move"></i>
604 <a href="javascript:;" class="open-tutor-quiz-modal" data-quiz-id="<?php echo $quiz_id; ?>" data-topic-id="<?php echo $topic_id;
605 ?>"> <i class=" tutor-icon-doubt"></i>[QUIZ] <?php echo $quiz_title; ?> </a>
606 <a href="javascript:;" class="tutor-delete-quiz-btn" data-quiz-id="<?php echo $quiz_id; ?>"><i class="tutor-icon-garbage"></i></a>
607 </div>
608 </div>
609 <?php
610 $output_quiz_row = ob_get_clean();
611
612 wp_send_json_success(array('output' => $output, 'output_quiz_row' => $output_quiz_row));
613 }
614
615 public function tutor_delete_quiz_by_id(){
616 global $wpdb;
617
618 $quiz_id = (int) sanitize_text_field($_POST['quiz_id']);
619 $post = get_post($quiz_id);
620
621 if ( $post->post_type === 'tutor_quiz'){
622 do_action('tutor_delete_quiz_before', $quiz_id);
623
624 $wpdb->delete($wpdb->prefix.'tutor_quiz_attempts', array('quiz_id' => $quiz_id));
625 $wpdb->delete($wpdb->prefix.'tutor_quiz_attempt_answers', array('quiz_id' => $quiz_id));
626
627 $questions_ids = $wpdb->get_col("SELECT question_id FROM {$wpdb->prefix}tutor_quiz_questions WHERE quiz_id = {$quiz_id} ");
628 if (is_array($questions_ids) && count($questions_ids)){
629 $in_question_ids = "'".implode("','", $questions_ids)."'";
630 $wpdb->query("DELETE FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE belongs_question_id IN({$in_question_ids}) ");
631 }
632 $wpdb->delete($wpdb->prefix.'tutor_quiz_questions', array('quiz_id' => $quiz_id));
633
634 wp_delete_post($quiz_id, true);
635 delete_post_meta($quiz_id, '_tutor_course_id_for_lesson');
636
637 do_action('tutor_delete_quiz_after', $quiz_id);
638
639
640 wp_send_json_success();
641 }
642
643 wp_send_json_error();
644 }
645
646 /**
647 * Update Quiz from quiz builder modal
648 *
649 * @since v.1.0.0
650 */
651 public function tutor_quiz_builder_quiz_update(){
652 $quiz_id = sanitize_text_field($_POST['quiz_id']);
653 $topic_id = sanitize_text_field($_POST['topic_id']);
654 $quiz_title = sanitize_text_field($_POST['quiz_title']);
655 $quiz_description = sanitize_text_field($_POST['quiz_description']);
656
657 $post_arr = array(
658 'ID' => $quiz_id,
659 'post_title' => $quiz_title,
660 'post_content' => $quiz_description,
661
662 );
663 $quiz_id = wp_update_post( $post_arr );
664
665 do_action('tutor_quiz_updated', $quiz_id);
666
667 ob_start();
668 ?>
669 <div class="tutor-lesson-top">
670 <i class="tutor-icon-move"></i>
671 <a href="javascript:;" class="open-tutor-quiz-modal" data-quiz-id="<?php echo $quiz_id; ?>" data-topic-id="<?php echo $topic_id;
672 ?>"> <i class=" tutor-icon-doubt"></i>[QUIZ] <?php echo $quiz_title; ?> </a>
673 <a href="javascript:;" class="tutor-delete-quiz-btn" data-quiz-id="<?php echo $quiz_id; ?>"><i class="tutor-icon-garbage"></i></a>
674 </div>
675 <?php
676 $output_quiz_row = ob_get_clean();
677
678 wp_send_json_success(array('output_quiz_row' => $output_quiz_row));
679 }
680
681 /**
682 * Load quiz Modal for edit quiz
683 *
684 * @since v.1.0.0
685 */
686 public function tutor_load_edit_quiz_modal(){
687 $quiz_id = sanitize_text_field($_POST['quiz_id']);
688
689 ob_start();
690 include tutor()->path.'views/modal/edit_quiz.php';
691 $output = ob_get_clean();
692
693 wp_send_json_success(array('output' => $output));
694 }
695
696 /**
697 * Load quiz question form for quiz
698 *
699 * @since v.1.0.0
700 */
701 public function tutor_quiz_builder_get_question_form(){
702 global $wpdb;
703 $quiz_id = sanitize_text_field($_POST['quiz_id']);
704 $question_id = sanitize_text_field(tutor_utils()->avalue_dot('question_id', $_POST));
705
706 if ( ! $question_id){
707 $next_question_id = tutor_utils()->quiz_next_question_id();
708 $next_question_order = tutor_utils()->quiz_next_question_order_id($quiz_id);
709
710 $new_question_data = array(
711 'quiz_id' => $quiz_id,
712 'question_title' => __('Question ').$next_question_id,
713 'question_description' => '',
714 'question_type' => 'true_false',
715 'question_mark' => 1,
716 'question_settings' => maybe_serialize(array()),
717 'question_order' => $next_question_order,
718 );
719
720 $wpdb->insert($wpdb->prefix.'tutor_quiz_questions', $new_question_data);
721 $question_id = $wpdb->insert_id;
722 }
723
724 $question = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions where question_id = {$question_id} ");
725
726 ob_start();
727 include tutor()->path.'views/modal/question_form.php';
728 $output = ob_get_clean();
729
730 wp_send_json_success(array('output' => $output));
731 }
732
733 public function tutor_quiz_modal_update_question(){
734 global $wpdb;
735
736 $question_data = $_POST['tutor_quiz_question'];
737
738 foreach ($question_data as $question_id => $question){
739 $question_title = sanitize_text_field($question['question_title']);
740 $question_description = $question['question_description'];
741 $question_type = $question['question_type'];
742 $question_mark = $question['question_mark'];
743
744 unset($question['question_title']);
745 unset($question['question_description']);
746
747 $data = array(
748 'question_title' => $question_title,
749 'question_description' => $question_description,
750 'question_type' => $question_type,
751 'question_mark' => $question_mark,
752 'question_settings' => maybe_serialize($question),
753 );
754
755 $wpdb->update($wpdb->prefix.'tutor_quiz_questions', $data, array('question_id' => $question_id) );
756
757
758 /**
759 * Validation
760 */
761 if ($question_type === 'true_false' || $question_type === 'single_choice'){
762 $question_options = tutils()->get_answers_by_quiz_question($question_id);
763 if (tutils()->count($question_options)){
764 $required_validate = true;
765 foreach ($question_options as $question_option){
766 if ($question_option->is_correct){
767 $required_validate = false;
768 }
769 }
770 if ($required_validate){
771 $validation_msg = "<p class='tutor-error-msg'>".__('Please select the correct answer', 'tutor')."</p>";
772 wp_send_json_error(array('validation_msg' => $validation_msg ));
773 }
774 }else{
775 $validation_msg = "<p class='tutor-error-msg'>".__('Please make sure you have added more than one option and saved them', 'tutor')."</p>";
776 wp_send_json_error(array('validation_msg' => $validation_msg ));
777 }
778 }
779 }
780
781 wp_send_json_success();
782 }
783
784 public function tutor_quiz_builder_question_delete(){
785 global $wpdb;
786
787 $question_id = sanitize_text_field(tutor_utils()->avalue_dot('question_id', $_POST));
788 if ($question_id){
789 $wpdb->delete($wpdb->prefix.'tutor_quiz_questions', array('question_id' => $question_id));
790 }
791
792 wp_send_json_success();
793 }
794
795 /**
796 * Get answers options form for quiz question
797 *
798 * @since v.1.0.0
799 */
800 public function tutor_quiz_add_question_answers(){
801 $question_id = sanitize_text_field($_POST['question_id']);
802 $question = tutor_utils()->avalue_dot($question_id, $_POST['tutor_quiz_question']);
803 $question_type = $question['question_type'];
804
805 ob_start();
806 include tutor()->path.'views/modal/question_answer_form.php';
807 $output = ob_get_clean();
808
809 wp_send_json_success(array('output' => $output));
810 }
811
812 /**
813 * Edit Answer Form
814 *
815 * @since v.1.0.0
816 */
817 public function tutor_quiz_edit_question_answer(){
818 $answer_id = (int) sanitize_text_field($_POST['answer_id']);
819 $old_answer = tutor_utils()->get_answer_by_id($answer_id);
820 foreach ($old_answer as $old_answer);
821 $question_id = $old_answer->belongs_question_id;
822 $question_type = $old_answer->belongs_question_type;
823
824 ob_start();
825 include tutor()->path.'views/modal/question_answer_edit_form.php';
826 $output = ob_get_clean();
827
828 wp_send_json_success(array('output' => $output));
829 }
830
831 public function tutor_save_quiz_answer_options(){
832 global $wpdb;
833
834 $questions = $_POST['tutor_quiz_question'];
835 $answers = $_POST['quiz_answer'];
836
837 foreach ($answers as $question_id => $answer){
838 $question = tutor_utils()->avalue_dot($question_id, $questions);
839 $question_type = $question['question_type'];
840
841 //Getting next sorting order
842 $next_order_id = (int) $wpdb->get_var("SELECT MAX(answer_order) FROM {$wpdb->prefix}tutor_quiz_question_answers where belongs_question_id = {$question_id} AND belongs_question_type = '{$question_type}' ");
843 $next_order_id = $next_order_id + 1;
844
845 if ($question){
846 if ($question_type === 'true_false'){
847 $wpdb->delete($wpdb->prefix.'tutor_quiz_question_answers', array('belongs_question_id' => $question_id, 'belongs_question_type' => $question_type));
848 $data_true_false = array(
849 array(
850 'belongs_question_id' => $question_id,
851 'belongs_question_type' => $question_type,
852 'answer_title' => __('True', 'tutor'),
853 'is_correct' => $answer['true_false'] == 'true' ? 1 : 0,
854 'answer_two_gap_match' => 'true',
855 ),
856 array(
857 'belongs_question_id' => $question_id,
858 'belongs_question_type' => $question_type,
859 'answer_title' => __('False', 'tutor'),
860 'is_correct' => $answer['true_false'] == 'false' ? 1 : 0,
861 'answer_two_gap_match' => 'false',
862 ),
863 );
864
865 foreach ($data_true_false as $true_false_data){
866 $wpdb->insert($wpdb->prefix.'tutor_quiz_question_answers', $true_false_data);
867 }
868
869 }elseif($question_type === 'multiple_choice' || $question_type === 'single_choice' || $question_type === 'ordering' ||
870 $question_type === 'matching' || $question_type === 'image_matching' || $question_type === 'image_answering' ){
871
872 $answer_data = array(
873 'belongs_question_id' => $question_id,
874 'belongs_question_type' => $question_type,
875 'answer_title' => $answer['answer_title'],
876 'image_id' => isset($answer['image_id']) ? $answer['image_id'] : 0,
877 'answer_view_format' => isset($answer['answer_view_format']) ? $answer['answer_view_format'] : 0,
878 'answer_order' => $next_order_id,
879 );
880 if (isset($answer['matched_answer_title'])){
881 $answer_data['answer_two_gap_match'] = $answer['matched_answer_title'];
882 }
883
884 $wpdb->insert($wpdb->prefix.'tutor_quiz_question_answers', $answer_data);
885
886 }elseif($question_type === 'fill_in_the_blank'){
887 $wpdb->delete($wpdb->prefix.'tutor_quiz_question_answers', array('belongs_question_id' => $question_id, 'belongs_question_type' => $question_type));
888 $answer_data = array(
889 'belongs_question_id' => $question_id,
890 'belongs_question_type' => $question_type,
891 'answer_title' => $answer['answer_title'],
892 'answer_two_gap_match' => isset($answer['answer_two_gap_match']) ? strtolower(trim($answer['answer_two_gap_match'])) : null,
893 );
894 $wpdb->insert($wpdb->prefix.'tutor_quiz_question_answers', $answer_data);
895 }
896 }
897 }
898
899 wp_send_json_success();
900 }
901
902 /**
903 * Tutor Update Answer
904 *
905 * @since v.1.0.0
906 */
907 public function tutor_update_quiz_answer_options(){
908 global $wpdb;
909
910 $answer_id = (int) sanitize_text_field($_POST['tutor_quiz_answer_id']);
911 $questions = $_POST['tutor_quiz_question'];
912 $answers = $_POST['quiz_answer'];
913
914 foreach ($answers as $question_id => $answer){
915 $question = tutor_utils()->avalue_dot($question_id, $questions);
916 $question_type = $question['question_type'];
917
918 if ($question){
919 if($question_type === 'multiple_choice' || $question_type === 'single_choice' || $question_type === 'ordering' || $question_type === 'matching' || $question_type === 'image_matching' || $question_type === 'fill_in_the_blank' || $question_type === 'image_answering' ){
920
921 $answer_data = array(
922 'belongs_question_id' => $question_id,
923 'belongs_question_type' => $question_type,
924 'answer_title' => $answer['answer_title'],
925 'image_id' => isset($answer['image_id']) ? $answer['image_id'] : 0,
926 'answer_view_format' => isset($answer['answer_view_format']) ? $answer['answer_view_format'] : '',
927 );
928 if (isset($answer['matched_answer_title'])){
929 $answer_data['answer_two_gap_match'] = $answer['matched_answer_title'];
930 }
931
932 if ($question_type === 'fill_in_the_blank'){
933 $answer_data['answer_two_gap_match'] = isset($answer['answer_two_gap_match']) ? strtolower(trim($answer['answer_two_gap_match'])) : null;
934 }
935
936 $wpdb->update($wpdb->prefix.'tutor_quiz_question_answers', $answer_data, array('answer_id' => $answer_id));
937 }
938 }
939 }
940
941 //die(print_r($_POST));
942 wp_send_json_success();
943 }
944
945 public function tutor_quiz_builder_get_answers_by_question(){
946 global $wpdb;
947 $question_id = sanitize_text_field($_POST['question_id']);
948 $question_type = sanitize_text_field($_POST['question_type']);
949
950 $question = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_questions WHERE question_id = {$question_id} ");
951 $answers = $wpdb->get_results("SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers where belongs_question_id = {$question_id} AND belongs_question_type = '{$question_type}' order by answer_order asc ;");
952
953 ob_start();
954
955 /*
956 * @TODO: Should We remove this text?
957 * Screenshot: http://prntscr.com/ngl2mb
958 * Screenshot: http://prntscr.com/ngl2ak
959 */
960
961 switch ($question_type){
962 case 'true_false':
963 echo '<label>'.__('Answer options &amp; mark correct', 'tutor').'</label>';
964 break;
965 case 'ordering':
966 echo '<label>'.__('Make sure you’re saving the answers in the right order. Students will have to match this order exactly.', 'tutor').'</label>';
967 break;
968 }
969
970 if (is_array($answers) && count($answers)){
971 foreach ($answers as $answer){
972 ?>
973 <div class="tutor-quiz-answer-wrap" data-answer-id="<?php echo $answer->answer_id; ?>">
974 <div class="tutor-quiz-answer">
975 <span class="tutor-quiz-answer-title">
976 <?php
977 echo stripslashes($answer->answer_title);
978 if ($answer->belongs_question_type === 'fill_in_the_blank'){
979 echo ' ('.__('Answer', 'tutor').' : ';
980 echo "<strong>{$answer->answer_two_gap_match} </strong>)";
981 }
982 if ($answer->belongs_question_type === 'matching'){
983 echo " - {$answer->answer_two_gap_match}";
984 }
985 ?>
986 </span>
987
988 <?php
989 if ($answer->image_id){
990 echo '<span class="tutor-question-answer-image"><img src="'.wp_get_attachment_image_url($answer->image_id).'" /> </span>';
991 }
992 if ($question_type === 'true_false' || $question_type === 'single_choice'){
993 ?>
994 <span class="tutor-quiz-answers-mark-correct-wrap">
995 <input type="radio" name="mark_as_correct[<?php echo $answer->belongs_question_id; ?>]" value="<?php echo $answer->answer_id; ?>" title="<?php _e('Mark as correct', 'tutor'); ?>" <?php checked(1, $answer->is_correct); ?> >
996 </span>
997 <?php
998 }elseif ($question_type === 'multiple_choice'){
999 ?>
1000 <span class="tutor-quiz-answers-mark-correct-wrap">
1001 <input type="checkbox" name="mark_as_correct[<?php echo $answer->belongs_question_id; ?>]" value="<?php echo $answer->answer_id; ?>" title="<?php _e('Mark as correct', 'tutor'); ?>" <?php checked(1, $answer->is_correct); ?> >
1002 </span>
1003 <?php
1004 }
1005 ?>
1006 <span class="tutor-quiz-answer-edit">
1007 <a href="javascript:;"><i class="tutor-icon-pencil"></i> </a>
1008 </span>
1009 <span class="tutor-quiz-answer-sort-icon"><i class="tutor-icon-menu-2"></i> </span>
1010 </div>
1011
1012 <div class="tutor-quiz-answer-trash-wrap">
1013 <a href="javascript:;" class="answer-trash-btn" data-answer-id="<?php echo $answer->answer_id; ?>"><i class="tutor-icon-garbage"></i> </a>
1014 </div>
1015 </div>
1016 <?php
1017 }
1018 }
1019 $output = ob_get_clean();
1020
1021 wp_send_json_success(array('output' => $output));
1022 }
1023
1024 public function tutor_quiz_builder_delete_answer(){
1025 global $wpdb;
1026 $answer_id = sanitize_text_field($_POST['answer_id']);
1027
1028 $wpdb->delete($wpdb->prefix.'tutor_quiz_question_answers', array('answer_id' => $answer_id));
1029 wp_send_json_success();
1030 }
1031
1032 /**
1033 * Save quiz questions sorting
1034 */
1035 public function tutor_quiz_question_sorting(){
1036 global $wpdb;
1037
1038 $question_ids = tutor_utils()->avalue_dot('sorted_question_ids', $_POST);
1039 if (is_array($question_ids) && count($question_ids) ){
1040 $i = 0;
1041 foreach ($question_ids as $key => $question_id){
1042 $i++;
1043 $wpdb->update($wpdb->prefix.'tutor_quiz_questions', array('question_order' => $i), array('question_id' => $question_id));
1044 }
1045 }
1046 }
1047
1048 /**
1049 * Save sorting data for quiz answers
1050 */
1051 public function tutor_quiz_answer_sorting(){
1052 global $wpdb;
1053
1054 if ( ! empty($_POST['sorted_answer_ids']) && is_array($_POST['sorted_answer_ids']) && count($_POST['sorted_answer_ids']) ){
1055 $answer_ids = $_POST['sorted_answer_ids'];
1056 $i = 0;
1057 foreach ($answer_ids as $key => $answer_id){
1058 $i++;
1059 $wpdb->update($wpdb->prefix.'tutor_quiz_question_answers', array('answer_order' => $i), array('answer_id' => $answer_id));
1060 }
1061 }
1062
1063 }
1064
1065 /**
1066 * Mark answer as correct
1067 */
1068
1069 public function tutor_mark_answer_as_correct(){
1070 global $wpdb;
1071
1072 $answer_id = sanitize_text_field($_POST['answer_id']);
1073 $inputValue = sanitize_text_field($_POST['inputValue']);
1074
1075 $answer = $wpdb->get_row("SELECT * FROM {$wpdb->prefix}tutor_quiz_question_answers WHERE answer_id = {$answer_id} LIMIT 0,1 ;");
1076 if ($answer->belongs_question_type === 'single_choice'){
1077 $wpdb->update($wpdb->prefix.'tutor_quiz_question_answers', array('is_correct' => 0), array('belongs_question_id' => $answer->belongs_question_id));
1078 }
1079 $wpdb->update($wpdb->prefix.'tutor_quiz_question_answers', array('is_correct' => $inputValue), array('answer_id' => $answer_id));
1080 }
1081
1082 /**
1083 * Update quiz settings from modal
1084 *
1085 * @since : v.1.0.0
1086 */
1087 public function tutor_quiz_modal_update_settings(){
1088 $quiz_id = sanitize_text_field($_POST['quiz_id']);
1089
1090 $quiz_option = tutor_utils()->sanitize_array($_POST['quiz_option']);
1091 update_post_meta($quiz_id, 'tutor_quiz_option', $quiz_option);
1092
1093 do_action('tutor_quiz_settings_updated', $quiz_id);
1094
1095 wp_send_json_success();
1096 }
1097
1098
1099 //=========================//
1100 // Front end stuffs
1101 //=========================//
1102
1103 /**
1104 * Rendering quiz for frontend
1105 *
1106 * @since v.1.0.0
1107 */
1108
1109 public function tutor_render_quiz_content(){
1110 $quiz_id = (int) sanitize_text_field(tutor_utils()->avalue_dot('quiz_id', $_POST));
1111
1112 ob_start();
1113 global $post;
1114
1115 $post = get_post($quiz_id);
1116 setup_postdata($post);
1117 //tutor_lesson_content();
1118
1119 single_quiz_contents();
1120
1121 wp_reset_postdata();
1122
1123
1124 $html = ob_get_clean();
1125 wp_send_json_success(array('html' => $html));
1126 }
1127
1128
1129 }