PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.2.0
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.2.0
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.2.0, at inc/rest-api/v1/frontend/class-lp-rest-users-controller.php

425 lines 12.2 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 $quiz->set_course( $course );
170
171 do_action( 'learn-press/user/before/start-quiz', $item_id, $course_id, $user_id );
172
173 // For no required enroll course
174 if ( $user->is_guest() && $course->is_no_required_enroll() ) {
175 $no_required_enroll = new LP_Course_No_Required_Enroll( $course );
176 $response = $no_required_enroll->guest_start_quiz( $quiz );
177
178 return rest_ensure_response( $response );
179 }
180
181 /**
182 * Require enroll course
183 *
184 * @var LP_User_Item_Quiz|WP_Error $user_quiz
185 */
186 if ( $user->has_started_quiz( $item_id, $course_id ) ) {
187 $user_quiz = $user->retake_quiz( $item_id, $course_id, true );
188 $results['answered'] = []; // Reset answered for js
189 } else {
190 $user_quiz = $user->start_quiz( $item_id, $course_id, true );
191 }
192
193 if ( is_wp_error( $user_quiz ) ) {
194 throw new Exception( $user_quiz->get_error_message() );
195 }
196
197 /**
198 * Clear cache result quiz
199 * Cache set on @see LP_User_Item_Quiz::get_results
200 */
201 $lp_quiz_cache = LP_Quiz_Cache::instance();
202 $key_cache = sprintf( '%d/user/%d/course/%d', $item_id, $user_id, $course_id );
203 $lp_quiz_cache->clear( $key_cache );
204 // End
205
206 $show_check = $quiz->get_instant_check();
207 $duration = $quiz->get_duration();
208 $show_correct_review = $quiz->get_show_correct_review();
209 $question_ids = $quiz->get_question_ids();
210 $status = $user_quiz->get_status();
211 $checked_questions = $user_quiz->get_checked_questions();
212 $hinted_questions = $user_quiz->get_hint_questions();
213 $time_remaining = $user_quiz->get_timestamp_remaining();
214
215 $questions = learn_press_rest_prepare_user_questions(
216 $question_ids,
217 array(
218 'instant_check' => $show_check,
219 'quiz_status' => $status,
220 'checked_questions' => $checked_questions,
221 'hinted_questions' => $hinted_questions,
222 'answered' => [],
223 'show_correct_review' => $show_correct_review,
224 )
225 );
226
227 $results['question_ids'] = $question_ids;
228 $results['questions'] = $questions;
229 $results['total_time'] = $time_remaining;
230 $results['duration'] = $duration ? $duration->get() : false;
231 $results['status'] = $status; // Must be started
232 $results['retaken'] = absint( $user_quiz->get_retaken_count() );
233 $results['attempts'] = $user_quiz->get_attempts();
234 $results['user_item_id'] = $user_quiz->get_user_item_id();
235 $response['status'] = 'success';
236 $response['results'] = $results;
237 } catch ( Throwable $e ) {
238 $response['message'] = $e->getMessage();
239 }
240
241 return rest_ensure_response( $response );
242 }
243
244 /**
245 * Submit quiz answer
246 *
247 * @param WP_REST_Request $request
248 *
249 * @return WP_Error|WP_HTTP_Response|WP_REST_Response
250 * @editor tungnx
251 * @modify 4.1.4.1
252 * @version 1.0.2
253 */
254 public function submit_quiz_new( WP_REST_Request $request ) {
255 //$response = new LP_REST_Response();
256 $response = array(
257 'status' => 'error',
258 'message' => '',
259 );
260
261 try {
262 $user_id = get_current_user_id();
263 $item_id = $request['item_id'] ?? 0;
264 $course_id = $request['course_id'] ?? 0;
265 $answered = $request['answered'] ?? [];
266 $time_spend = $request['time_spend'] ?? 0;
267 $user = learn_press_get_user( $user_id );
268 $course = learn_press_get_course( $course_id );
269
270 if ( ! $course ) {
271 throw new Exception( 'The course is invalid!' );
272 }
273 // Use for Review Quiz.
274 $quiz = learn_press_get_quiz( $item_id );
275 if ( ! $quiz ) {
276 throw new Exception( __( 'The quiz is invalid!', 'learnpress' ) );
277 }
278 $quiz->set_course( $course );
279
280 // Course is no required enroll
281 if ( $course->is_no_required_enroll() ) {
282 $no_required_enroll = new LP_Course_No_Required_Enroll( $course );
283
284 $result = $no_required_enroll->get_result_quiz( $quiz, $answered );
285
286 // Set time spent
287 $interval = new LP_Duration( $time_spend );
288 $interval = $interval->to_timer();
289 $result['time_spend'] = $interval;
290 // End
291
292 $result['status'] = LP_ITEM_COMPLETED;
293 //$result['answered'] = $result['questions'];
294 $result['attempts'] = [];
295 $result['results'] = $result;
296 $response['status'] = 'success';
297 $response['results'] = $result;
298
299 return rest_ensure_response( $response );
300 }
301
302 $user_course = $user->get_course_data( $course_id );
303
304 // Course required enroll
305 if ( ! $user_course ) {
306 throw new Exception( 'User not enrolled course!' );
307 }
308
309 /**
310 * @var LP_User_Item_Quiz $user_quiz
311 */
312 $user_quiz = $user_course->get_item( $item_id );
313 if ( ! $user_quiz ) {
314 throw new Exception();
315 }
316
317 // For case save result when check instant answer
318 $result_instant_check = LP_User_Items_Result_DB::instance()->get_result( $user_quiz->get_user_item_id() );
319 if ( $result_instant_check ) {
320 foreach ( $result_instant_check['questions'] as $question_answer_id => $question_answer ) {
321 if ( ! empty( $question_answer['answered'] ) ) {
322 $answered[ $question_answer_id ] = $question_answer['answered'];
323 }
324 }
325 }
326
327 // Set end time.
328 $start_time = $user_quiz->get_start_time()->getTimestamp();
329 $user_quiz->set_end_time( $start_time + $time_spend );
330
331 // Calculate quiz result and save.
332 $result = $user_quiz->calculate_quiz_result( $answered );
333 // Save
334 LP_User_Items_Result_DB::instance()->update( $user_quiz->get_user_item_id(), wp_json_encode( $result ) );
335
336 if ( $result['pass'] ) {
337 $user_quiz->set_graduation( LP_COURSE_GRADUATION_PASSED );
338 } else {
339 $user_quiz->set_graduation( LP_COURSE_GRADUATION_FAILED );
340 }
341
342 $user_quiz->complete();
343
344 do_action( 'learn-press/user/quiz-finished', $item_id, $course_id, $user_id );
345
346 $result['status'] = $user_quiz->get_status(); // Must be completed
347 $result['attempts'] = $user_quiz->get_attempts();
348 $result['answered'] = $result['questions'];
349 $result['results'] = $result;
350 $response['status'] = 'success';
351 $response['results'] = $result;
352 } catch ( Throwable $e ) {
353 $response['message'] = $e->getMessage();
354 }
355
356 return rest_ensure_response( $response );
357 }
358
359 /**
360 * Hint the question and response hint content.
361 *
362 * @param WP_REST_Request $request
363 *
364 * @return mixed|WP_REST_Response
365 */
366 public function hint_answer( $request ) {
367 $question_id = $request['question_id'];
368 $question = learn_press_get_question( $question_id );
369
370 $response = array(
371 'hint' => $question->get_hint(),
372 );
373
374 return rest_ensure_response( $response );
375 }
376
377 public function check_answer( $request ) {
378 $response = array(
379 'status' => 'error',
380 'message' => '',
381 );
382
383 try {
384 $question_id = $request['question_id'] ?? 0;
385 $answered = $request['answered'] ?? '';
386 $course_id = $request['course_id'] ?? 0;
387 $quiz_id = $request['item_id'] ?? 0;
388 $course = learn_press_get_course( $course_id );
389 $checked = [];
390
391 if ( $course->is_no_required_enroll() ) {
392 $no_required_enroll = new LP_Course_No_Required_Enroll( $course );
393 $checked = $no_required_enroll->guest_check_question( $question_id, $answered );
394 } else {
395 $user = learn_press_get_current_user();
396 if ( $user->is_guest() ) {
397 throw new Exception( 'The user is invalid', 'learnrpess' );
398 }
399
400 $user_course = $user->get_course_data( $course_id );
401 if ( ! $user_course ) {
402 throw new Exception( 'User\'s course no data!', 'learnrpess' );
403 }
404
405 $user_quiz = $user_course->get_item( $quiz_id );
406 if ( ! $user_quiz ) {
407 throw new Exception( 'User\'s quiz no data!', 'learnrpess' );
408 }
409
410 $checked = $user_quiz->instant_check_question( $question_id, $answered );
411 }
412
413 $question = learn_press_get_question( $question_id );
414 $response['explanation'] = $question->get_explanation();
415 $response['options'] = learn_press_get_question_options_for_js( $question, array( 'answer' => $answered ) );
416 $response['result'] = $checked;
417 $response['status'] = 'success';
418 } catch ( Throwable $e ) {
419 $response['message'] = $e->getMessage();
420 }
421
422 return rest_ensure_response( $response );
423 }
424 }
425