PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 2.7.5
Tutor LMS – eLearning and online course solution v2.7.5
3.9.15 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 / restapi / REST_Quiz.php
tutor / restapi Last commit date
REST_Author.php 2 years ago REST_Course.php 2 years ago REST_Course_Announcement.php 2 years ago REST_Lesson.php 2 years ago REST_Quiz.php 2 years ago REST_Rating.php 2 years ago REST_Response.php 2 years ago REST_Topic.php 2 years ago RestAuth.php 2 years ago
REST_Quiz.php
443 lines
1 <?php
2 /**
3 * REST API for quiz.
4 *
5 * @package Tutor\RestAPI
6 * @author Themeum <support@themeum.com>
7 * @link https://themeum.com
8 * @since 1.7.1
9 */
10
11 namespace TUTOR;
12
13 use Tutor\Helpers\QueryHelper;
14 use WP_REST_Request;
15
16 if ( ! defined( 'ABSPATH' ) ) {
17 exit;
18 }
19
20 /**
21 * Class REST_Quiz
22 */
23 class REST_Quiz {
24
25 use REST_Response;
26
27 /**
28 * Quiz post type
29 *
30 * @var string The post type for quizzes.
31 */
32 private $post_type = 'tutor_quiz';
33
34 /**
35 * Post parent ID
36 *
37 * @var int|null The post parent ID.
38 */
39 private $post_parent;
40
41 /**
42 * Quiz questions table name
43 *
44 * @var string The table name for quiz questions.
45 */
46 private $t_quiz_question = 'tutor_quiz_questions';
47
48 /**
49 * Quiz question answers table name
50 *
51 * @var string The table name for quiz question answers.
52 */
53 private $t_quiz_ques_ans = 'tutor_quiz_question_answers';
54
55 /**
56 * Quiz question answer options table name
57 *
58 * @var string The table name for quiz attempts.
59 */
60 private $t_quiz_attempt = 'tutor_quiz_attempts';
61
62 /**
63 * Quiz attempt answers table name
64 *
65 * @var string The table name for quiz attempt answers.
66 */
67 private $t_quiz_attempt_ans = 'tutor_quiz_attempt_answers';
68
69 /**
70 * Obtain quiz detail for a single quiz.
71 *
72 * @since 2.7.1
73 *
74 * @param WP_REST_Request $request REST request object.
75 *
76 * @return mixed
77 */
78 public function get_quiz( WP_REST_Request $request ) {
79 global $wpdb;
80
81 $quiz_id = Input::sanitize( $request->get_param( 'id' ), 0, Input::TYPE_INT );
82 $wpdb->q_t = $wpdb->prefix . $this->t_quiz_question; // Question table.
83
84 $wpdb->q_a_t = $wpdb->prefix . $this->t_quiz_ques_ans; // Question answer table.
85
86 $quiz = $wpdb->get_row(
87 $wpdb->prepare(
88 "SELECT
89 ID,
90 post_title,
91 post_content,
92 post_name
93 FROM {$wpdb->posts}
94 WHERE post_type = %s
95 AND ID = %d
96 ",
97 $this->post_type,
98 $quiz_id
99 )
100 );
101
102 if ( ! isset( $quiz ) ) {
103 $response = array(
104 'code' => 'not_found',
105 'message' => __( 'Quiz not found for given ID', 'tutor' ),
106 'data' => array(),
107 );
108 return self::send( $response );
109 }
110
111 $quiz->quiz_settings = get_post_meta( $quiz->ID, 'tutor_quiz_option', false );
112 $questions = $wpdb->get_results(
113 $wpdb->prepare(
114 "SELECT
115 question_id,
116 question_title,
117 question_description,
118 question_type,
119 question_mark,
120 question_settings FROM {$wpdb->q_t}
121 WHERE quiz_id = %d
122 ",
123 $quiz->ID
124 )
125 );
126
127 foreach ( $questions as $question ) {
128 if ( isset( $quiz->question_settings ) ) {
129 $question->question_settings = maybe_unserialize( $quiz->question_settings );
130 }
131
132 // question options with correct ans.
133 $options = $wpdb->get_results(
134 $wpdb->prepare(
135 "SELECT
136 answer_id,
137 answer_title,
138 is_correct FROM {$wpdb->q_a_t}
139 WHERE belongs_question_id = %d
140 ",
141 $question->question_id
142 )
143 );
144 $question->question_answers = $options;
145
146 }
147 $quiz->quiz_questions = $questions;
148
149 $response = array(
150 'code' => 'success',
151 'message' => __( 'Quiz retrieved successfully', 'tutor' ),
152 'data' => $quiz,
153 );
154
155 return self::send( $response );
156 }
157
158 /**
159 * Get quiz with settings.
160 *
161 * @since 1.7.1
162 *
163 * @param WP_REST_Request $request REST request object.
164 *
165 * @return mixed
166 */
167 public function quiz_with_settings( WP_REST_Request $request ) {
168 $this->post_parent = $request->get_param( 'topic_id' );
169
170 global $wpdb;
171
172 $quizs = $wpdb->get_results(
173 $wpdb->prepare(
174 "SELECT
175 ID,
176 post_title,
177 post_content,
178 post_name
179 FROM {$wpdb->posts}
180 WHERE post_type = %s
181 AND post_parent = %d
182 ",
183 $this->post_type,
184 $this->post_parent
185 )
186 );
187
188 $data = array();
189
190 if ( count( $quizs ) > 0 ) {
191 foreach ( $quizs as $quiz ) {
192 $quiz->quiz_settings = get_post_meta( $quiz->ID, 'tutor_quiz_option', false );
193
194 array_push( $data, $quiz );
195
196 $response = array(
197 'code' => 'success',
198 'message' => __( 'Quiz retrieved successfully', 'tutor' ),
199 'data' => $data,
200 );
201 }
202 return self::send( $response );
203 }
204
205 $response = array(
206 'code' => 'not_found',
207 'message' => __( 'Quiz not found for given ID', 'tutor' ),
208 'data' => $data,
209 );
210 return self::send( $response );
211 }
212
213 /**
214 * Get quiz question and answers.
215 *
216 * @param WP_REST_Request $request REST request object.
217 *
218 * @return mixed
219 */
220 public function quiz_question_ans( WP_REST_Request $request ) {
221 global $wpdb;
222
223 $this->post_parent = $request->get_param( 'id' );
224
225 $wpdb->q_t = $wpdb->prefix . $this->t_quiz_question; // Question table.
226
227 $wpdb->q_a_t = $wpdb->prefix . $this->t_quiz_ques_ans; // Question answer table.
228
229 $quizs = $wpdb->get_results(
230 $wpdb->prepare(
231 "SELECT
232 question_id,
233 question_title,
234 question_description,
235 question_type,
236 question_mark,
237 question_settings FROM {$wpdb->q_t}
238 WHERE quiz_id = %d
239 ",
240 $this->post_parent
241 )
242 );
243 $data = array();
244
245 if ( count( $quizs ) > 0 ) {
246 // Get question ans by question_id.
247 foreach ( $quizs as $quiz ) {
248 // Un-serialized question settings.
249 $quiz->question_settings = maybe_unserialize( $quiz->question_settings );
250
251 // question options with correct ans.
252 $options = $wpdb->get_results(
253 $wpdb->prepare(
254 "SELECT
255 answer_id,
256 answer_title,
257 is_correct FROM {$wpdb->q_a_t}
258 WHERE belongs_question_id = %d
259 ",
260 $quiz->question_id
261 )
262 );
263
264 // set question_answers as quiz property.
265 $quiz->question_answers = $options;
266
267 array_push( $data, $quiz );
268 }
269
270 $response = array(
271 'code' => 'success',
272 'message' => __( 'Question retrieved successfully', 'tutor' ),
273 'data' => $data,
274 );
275
276 return self::send( $response );
277 }
278
279 $response = array(
280 'code' => 'not_found',
281 'message' => __( 'Question not found for given ID', 'tutor' ),
282 'data' => array(),
283 );
284
285 return self::send( $response );
286 }
287
288 /**
289 * Get quiz attempt details.
290 *
291 * @since 1.7.1
292 *
293 * @param WP_REST_Request $request REST request object.
294 *
295 * @return mixed
296 */
297 public function quiz_attempt_details( WP_REST_Request $request ) {
298 global $wpdb;
299
300 $quiz_id = $request->get_param( 'id' );
301
302 $wpdb->quiz_attempt = $wpdb->prefix . $this->t_quiz_attempt;
303
304 $attempts = $wpdb->get_results(
305 $wpdb->prepare(
306 "SELECT
307 att.user_id,
308 att.total_questions,
309 att.total_answered_questions,
310 att.total_marks,
311 att.earned_marks,
312 att.attempt_info,
313 att.attempt_status,
314 att.attempt_started_at,
315 att.attempt_ended_at,
316 att.is_manually_reviewed,
317 att.manually_reviewed_at
318 FROM {$wpdb->quiz_attempt} att
319 WHERE att.quiz_id = %d
320 ",
321 $quiz_id
322 )
323 );
324
325 if ( count( $attempts ) > 0 ) {
326 // unserialize each attempt info.
327 foreach ( $attempts as $key => $attempt ) {
328 $attempt->attempt_info = maybe_unserialize( $attempt->attempt_info );
329 // attach attempt ans.
330 $answers = $this->get_quiz_attempt_ans( $quiz_id );
331
332 if ( false !== $answers ) {
333 $attempt->attempts_answer = $answers;
334 } else {
335 $attempt->attempts_answer = array();
336 }
337 }
338
339 $response = array(
340 'code' => 'success',
341 'message' => __( 'Quiz attempts retrieved successfully', 'tutor' ),
342 'data' => $attempts,
343 );
344
345 return self::send( $response );
346 }
347
348 $response = array(
349 'code' => 'not_found',
350 'message' => __( 'Quiz attempts not found for given ID', 'tutor' ),
351 'data' => array(),
352 );
353
354 return self::send( $response );
355 }
356
357 /**
358 * Get quiz attempt answers.
359 *
360 * @since 1.7.1
361 *
362 * @param int $quiz_id quiz id.
363 *
364 * @return mixed
365 */
366 protected function get_quiz_attempt_ans( $quiz_id ) {
367 global $wpdb;
368 $wpdb->quiz_attempt_ans = $wpdb->prefix . $this->t_quiz_attempt_ans;
369 $wpdb->quiz_question = $wpdb->prefix . $this->t_quiz_question;
370
371 // get attempt answers.
372 $answers = $wpdb->get_results(
373 $wpdb->prepare(
374 "SELECT
375 q.question_title,
376 att_ans.given_answer,
377 att_ans.question_mark,
378 att_ans.achieved_mark,
379 att_ans.minus_mark,
380 att_ans.is_correct FROM {$wpdb->quiz_attempt_ans} as att_ans
381 JOIN {$wpdb->quiz_question} q ON q.question_id = att_ans.question_id
382 WHERE att_ans.quiz_id = %d
383 ",
384 $quiz_id
385 )
386 );
387
388 if ( count( $answers ) > 0 ) {
389 // unserialize each given answer.
390 foreach ( $answers as $key => $answer ) {
391 $answer->given_answer = maybe_unserialize( $answer->given_answer );
392
393 if ( is_numeric( $answer->given_answer ) || is_array( $answer->given_answer ) ) {
394 $ids = $answer->given_answer;
395 $ans_title = $this->answer_titles_by_id( $ids );
396 $answer->given_answer = $ans_title;
397 }
398 }
399
400 return $answers;
401 }
402 return false;
403 }
404
405 /**
406 * Get answer titles by id.
407 *
408 * @since 1.7.1
409 *
410 * @param int $id answer id.
411 *
412 * @return mixed
413 */
414 protected function answer_titles_by_id( $id ) {
415 global $wpdb;
416 $wpdb->t_quiz_ques_ans = $wpdb->prefix . $this->t_quiz_ques_ans;
417
418 if ( is_array( $id ) ) {
419 $array = QueryHelper::prepare_in_clause( $id );
420
421 $results = $wpdb->get_results(
422 "SELECT
423 answer_title
424 FROM {$wpdb->t_quiz_ques_ans}
425 WHERE
426 answer_id IN ('" . $array . "')"//phpcs:ignore
427 );
428 } else {
429 $results = $wpdb->get_results(
430 $wpdb->prepare(
431 "SELECT
432 answer_title
433 FROM {$wpdb->t_quiz_ques_ans}
434 WHERE answer_id = %d",
435 $id
436 )
437 );
438 }
439
440 return $results;
441 }
442 }
443