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