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

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