PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.3.2
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.3.2
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / rest-api / v1 / frontend / class-lp-rest-users-controller.php

class-lp-rest-users-controller.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7.3.2, at inc/rest-api/v1/frontend/class-lp-rest-users-controller.php

430 lines 12.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_REST_Users_Controller
5 *
6 * @since 3.3.0
7 */
8 class LP_REST_Users_Controller extends LP_Abstract_REST_Controller {
9 /**
10 * @var LP_User
11 */
12 protected $user = null;
13
14 /**
15 * @var LP_Course
16 */
17 protected $course = null;
18
19 /**
20 * @var LP_Course_Item|LP_Quiz|LP_Lesson
21 */
22 protected $item = null;
23
24 /**
25 * @var LP_User_Item_Course
26 */
27 protected $user_course = null;
28
29 /**
30 * @var LP_User_Item|LP_User_Item_Quiz
31 */
32 protected $user_item = null;
33
34 public function __construct() {
35 $this->namespace = 'lp/v1';
36 $this->rest_base = 'users';
37 parent::__construct();
38 }
39
40 /**
41 * Register rest routes.
42 */
43 public function register_routes() {
44 $this->routes = array(
45 'start-quiz' => array(
46 array(
47 'methods' => WP_REST_Server::EDITABLE,
48 'callback' => array( $this, 'start_quiz' ),
49 // 'permission_callback' => array( $this, 'check_admin_permission' ),
50 'permission_callback' => '__return_true',
51 'args' => $this->get_item_endpoint_args(),
52 ),
53 ),
54 'submit-quiz' => array(
55 array(
56 'methods' => WP_REST_Server::EDITABLE,
57 // 'callback' => array( $this, 'submit_quiz' ),
58 'callback' => array( $this, 'submit_quiz_new' ),
59 // 'permission_callback' => array( $this, 'check_admin_permission' ),
60 'permission_callback' => '__return_true',
61 'args' => $this->get_item_endpoint_args(),
62 ),
63 ),
64 'hint-answer' => array(
65 array(
66 'methods' => WP_REST_Server::EDITABLE,
67 'callback' => array( $this, 'hint_answer' ),
68 // 'permission_callback' => array( $this, 'check_admin_permission' ),
69 'permission_callback' => '__return_true',
70 'args' => $this->get_item_endpoint_args(),
71 ),
72 ),
73 'check-answer' => array(
74 array(
75 'methods' => WP_REST_Server::EDITABLE,
76 'callback' => array( $this, 'check_answer' ),
77 // 'permission_callback' => array( $this, 'check_admin_permission' ),
78 'permission_callback' => '__return_true',
79 'args' => $this->get_item_endpoint_args(),
80 ),
81 ),
82 );
83
84 parent::register_routes();
85 }
86
87 /**
88 * Get args for user item endpoints.
89 *
90 * @return array
91 */
92 public function get_item_endpoint_args() {
93 return array(
94 'item_id' => array(
95 'description' => __( 'The ID of the course item object.', 'learnpress' ),
96 'type' => 'int',
97 'validate_callback' => array( $this, 'validate_arg' ),
98 'required' => true,
99 ),
100 'course_id' => array(
101 'description' => __( 'The ID of the course object.', 'learnpress' ),
102 'type' => 'int',
103 'validate_callback' => array( $this, 'validate_arg' ),
104 'required' => true,
105 ),
106 );
107 }
108
109 /**
110 * Validation callback to verify rest args.
111 *
112 * @param mixed $value
113 * @param WP_REST_Request $request
114 * @param string $param
115 *
116 * @return bool|WP_Error
117 */
118 public function validate_arg( $value, $request, $param ) {
119 $attributes = $request->get_attributes();
120
121 if ( ! isset( $attributes['args'][ $param ] ) ) {
122 return new WP_Error( 'rest_invalid_param', sprintf( __( '%s was not registered as a request argument.', 'learnpress' ), $param ), array( 'status' => 400 ) );
123 }
124
125 return true;
126 }
127
128 public function check_admin_permission() {
129 return LP_Abstract_API::check_admin_permission();
130 }
131
132 /**
133 * User starts a quiz.
134 *
135 * @param WP_REST_Request $request
136 *
137 * @editor tungnx
138 * @version 1.0.1
139 * @sicne 4.0.0
140 * @return WP_REST_Response
141 */
142 public function start_quiz( WP_REST_Request $request ): WP_REST_Response {
143 $user_id = get_current_user_id();
144 $item_id = $request['item_id'] ?? 0;
145 $course_id = $request['course_id'] ?? 0;
146 $results = array(
147 'question_ids' => array(),
148 'questions' => array(),
149 'total_time' => 0,
150 );
151 $response = array(
152 'status' => 'error',
153 'message' => '',
154 );
155
156 try {
157 $user = learn_press_get_user( $user_id );
158 $course = learn_press_get_course( $course_id );
159 $quiz = learn_press_get_quiz( $item_id );
160
161 if ( ! $course ) {
162 throw new Exception( __( 'The course is invalid!', 'learnpress' ) );
163 }
164
165 if ( ! $quiz ) {
166 throw new Exception( __( 'The quiz is invalid!', 'learnpress' ) );
167 }
168
169 do_action( 'learn-press/user/before/start-quiz', $item_id, $course_id, $user_id );
170
171 // For no required enroll course
172 if ( $user->is_guest() && $course->is_no_required_enroll() ) {
173 if ( $quiz->get_retake_count() >= 0 ) {
174 //learn_press_remove_cookie( 'quiz_submit_status_' . $course_id . '_' . $item_id . '' );
175 }
176 $no_required_enroll = new LP_Course_No_Required_Enroll( $course );
177 $response = $no_required_enroll->guest_start_quiz( $quiz );
178
179 return rest_ensure_response( $response );
180 }
181
182 // Require enroll course
183 if ( $user->has_started_quiz( $item_id, $course_id ) ) {
184 /**
185 * @var LP_User_Item_Quiz $user_quiz
186 */
187 $user_quiz = $user->retake_quiz( $item_id, $course_id, true );
188 $results['answered'] = []; // Reset answered before on js
189 } else {
190 /**
191 * @var LP_User_Item_Quiz $user_quiz
192 */
193 $user_quiz = $user->start_quiz( $item_id, $course_id, true );
194 }
195
196 if ( is_wp_error( $user_quiz ) ) {
197 throw new Exception( $user_quiz->get_error_message() );
198 }
199
200 /**
201 * Clear cache result quiz
202 * Cache set on @see LP_User_Item_Quiz::get_results
203 */
204 $lp_quiz_cache = LP_Quiz_Cache::instance();
205 $key_cache = sprintf( '%d/user/%d/course/%d', $item_id, $user_id, $course_id );
206 $lp_quiz_cache->clear( $key_cache );
207 // End
208
209 $quiz->set_course( $course );
210
211 $show_check = $quiz->get_instant_check();
212 $duration = $quiz->get_duration();
213 $show_correct_review = $quiz->get_show_correct_review();
214 $question_ids = $quiz->get_question_ids();
215 $status = $user_quiz->get_status();
216 $checked_questions = $user_quiz->get_checked_questions();
217 $hinted_questions = $user_quiz->get_hint_questions();
218 $time_remaining = $user_quiz->get_timestamp_remaining();
219
220 $questions = learn_press_rest_prepare_user_questions(
221 $question_ids,
222 array(
223 'instant_check' => $show_check,
224 'quiz_status' => $status,
225 'checked_questions' => $checked_questions,
226 'hinted_questions' => $hinted_questions,
227 'answered' => [],
228 'show_correct_review' => $show_correct_review,
229 )
230 );
231
232 $results['question_ids'] = $question_ids;
233 $results['questions'] = $questions;
234 $results['total_time'] = $time_remaining;
235 $results['duration'] = $duration ? $duration->get() : false;
236 $results['status'] = $status; // Must be started
237 $results['retaken'] = absint( $user_quiz->get_retaken_count() );
238 $results['attempts'] = $user_quiz->get_attempts();
239 $results['user_item_id'] = $user_quiz->get_user_item_id();
240 $response['status'] = 'success';
241 $response['results'] = $results;
242 } catch ( Throwable $e ) {
243 $response['message'] = $e->getMessage();
244 }
245
246 return rest_ensure_response( $response );
247 }
248
249 /**
250 * Submit quiz answer
251 *
252 * @param WP_REST_Request $request
253 *
254 * @return WP_Error|WP_HTTP_Response|WP_REST_Response
255 * @editor tungnx
256 * @modify 4.1.4.1
257 * @version 1.0.2
258 */
259 public function submit_quiz_new( WP_REST_Request $request ) {
260 //$response = new LP_REST_Response();
261 $response = array(
262 'status' => 'error',
263 'message' => '',
264 );
265
266 try {
267 $user_id = get_current_user_id();
268 $item_id = $request['item_id'] ?? 0;
269 $course_id = $request['course_id'] ?? 0;
270 $answered = $request['answered'] ?? [];
271 $time_spend = $request['time_spend'] ?? 0;
272 $user = learn_press_get_user( $user_id );
273 $course = learn_press_get_course( $course_id );
274
275 if ( ! $course ) {
276 throw new Exception( 'The course is invalid!' );
277 }
278 // Use for Review Quiz.
279 $quiz = learn_press_get_quiz( $item_id );
280 if ( ! $quiz ) {
281 throw new Exception( __( 'The quiz is invalid!', 'learnpress' ) );
282 }
283 $quiz->set_course( $course );
284
285 // Course is no required enroll
286 if ( $course->is_no_required_enroll() ) {
287 $no_required_enroll = new LP_Course_No_Required_Enroll( $course );
288
289 $result = $no_required_enroll->get_result_quiz( $quiz, $answered );
290
291 // Set time spent
292 $interval = new LP_Duration( $time_spend );
293 $interval = $interval->to_timer();
294 $result['time_spend'] = $interval;
295 // End
296
297 $result['status'] = LP_ITEM_COMPLETED;
298 //$result['answered'] = $result['questions'];
299 $result['attempts'] = [];
300 $result['results'] = $result;
301 $response['status'] = 'success';
302 $response['results'] = $result;
303
304 return rest_ensure_response( $response );
305 }
306
307 $user_course = $user->get_course_data( $course_id );
308
309 // Course required enroll
310 if ( ! $user_course ) {
311 throw new Exception( 'User not enrolled course!' );
312 }
313
314 /**
315 * @var LP_User_Item_Quiz $user_quiz
316 */
317 $user_quiz = $user_course->get_item( $item_id );
318 if ( ! $user_quiz ) {
319 throw new Exception();
320 }
321
322 // For case save result when check instant answer
323 $result_instant_check = LP_User_Items_Result_DB::instance()->get_result( $user_quiz->get_user_item_id() );
324 if ( $result_instant_check ) {
325 foreach ( $result_instant_check['questions'] as $question_answer_id => $question_answer ) {
326 if ( ! empty( $question_answer['answered'] ) ) {
327 $answered[ $question_answer_id ] = $question_answer['answered'];
328 }
329 }
330 }
331
332 // Set end time.
333 $start_time = $user_quiz->get_start_time()->getTimestamp();
334 $user_quiz->set_end_time( $start_time + $time_spend );
335
336 // Calculate quiz result and save.
337 $result = $user_quiz->calculate_quiz_result( $answered );
338 // Save
339 LP_User_Items_Result_DB::instance()->update( $user_quiz->get_user_item_id(), wp_json_encode( $result ) );
340
341 if ( $result['pass'] ) {
342 $user_quiz->set_graduation( LP_COURSE_GRADUATION_PASSED );
343 } else {
344 $user_quiz->set_graduation( LP_COURSE_GRADUATION_FAILED );
345 }
346
347 $user_quiz->complete();
348
349 do_action( 'learn-press/user/quiz-finished', $item_id, $course_id, $user_id );
350
351 $result['status'] = $user_quiz->get_status(); // Must be completed
352 $result['attempts'] = $user_quiz->get_attempts();
353 $result['answered'] = $result['questions'];
354 $result['results'] = $result;
355 $response['status'] = 'success';
356 $response['results'] = $result;
357 } catch ( Throwable $e ) {
358 $response['message'] = $e->getMessage();
359 }
360
361 return rest_ensure_response( $response );
362 }
363
364 /**
365 * Hint the question and response hint content.
366 *
367 * @param WP_REST_Request $request
368 *
369 * @return mixed|WP_REST_Response
370 */
371 public function hint_answer( $request ) {
372 $question_id = $request['question_id'];
373 $question = learn_press_get_question( $question_id );
374
375 $response = array(
376 'hint' => $question->get_hint(),
377 );
378
379 return rest_ensure_response( $response );
380 }
381
382 public function check_answer( $request ) {
383 $response = array(
384 'status' => 'error',
385 'message' => '',
386 );
387
388 try {
389 $question_id = $request['question_id'] ?? 0;
390 $answered = $request['answered'] ?? '';
391 $course_id = $request['course_id'] ?? 0;
392 $quiz_id = $request['item_id'] ?? 0;
393 $course = learn_press_get_course( $course_id );
394 $checked = [];
395
396 if ( $course->is_no_required_enroll() ) {
397 $no_required_enroll = new LP_Course_No_Required_Enroll( $course );
398 $checked = $no_required_enroll->guest_check_question( $question_id, $answered );
399 } else {
400 $user = learn_press_get_current_user();
401 if ( $user->is_guest() ) {
402 throw new Exception( 'The user is invalid', 'learnrpess' );
403 }
404
405 $user_course = $user->get_course_data( $course_id );
406 if ( ! $user_course ) {
407 throw new Exception( 'User\'s course no data!', 'learnrpess' );
408 }
409
410 $user_quiz = $user_course->get_item( $quiz_id );
411 if ( ! $user_quiz ) {
412 throw new Exception( 'User\'s quiz no data!', 'learnrpess' );
413 }
414
415 $checked = $user_quiz->instant_check_question( $question_id, $answered );
416 }
417
418 $question = learn_press_get_question( $question_id );
419 $response['explanation'] = $question->get_explanation();
420 $response['options'] = learn_press_get_question_options_for_js( $question, array( 'answer' => $answered ) );
421 $response['result'] = $checked;
422 $response['status'] = 'success';
423 } catch ( Throwable $e ) {
424 $response['message'] = $e->getMessage();
425 }
426
427 return rest_ensure_response( $response );
428 }
429 }
430