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