PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
4.4.9.1 4.4.9 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 All 141 releases
← All changes | inc/rest-api/v1/admin/class-lp-admin-rest-tools-controller.php +383 -88 4.1.7.3.2 → 4.4.9 View file →
@@ -1,12 +1,16 @@
1 1 <?php
2 2
3 +use LearnPress\Filters\Course\CourseJsonFilter;
4 +use LearnPress\Models\Courses;
5 +use LearnPress\Models\UserItems\UserCourseModel;
6 +
3 7 /**
4 8 * Class LP_REST_Admin_Tools_Controller
5 9 *
6 10 * @since 4.0.3
7 11 * @author tungnx
8 - * @version 1.0.1
12 + * @version 1.0.3
9 13 */
10 14 class LP_REST_Admin_Tools_Controller extends LP_Abstract_REST_Controller {
11 15 public function __construct() {
12 16 $this->namespace = 'lp/v1/admin';
@@ -18,36 +22,71 @@
18 22 * Register rest routes.
19 23 */
20 24 public function register_routes() {
21 25 $this->routes = array(
22 - 'create-indexs' => array(
26 + 'create-indexs' => array(
23 27 array(
24 28 'methods' => WP_REST_Server::CREATABLE,
25 - 'callback' => array( $this, 'create_indexs' ),
26 - 'permission_callback' => '__return_true',
29 + 'callback' => array( $this, 'create_indexes' ),
30 + 'permission_callback' => array( $this, 'check_permission' ),
27 31 ),
28 32 ),
29 - 'list-tables-indexs' => array(
33 + 'list-tables-indexs' => array(
30 34 array(
31 35 'methods' => WP_REST_Server::CREATABLE,
32 36 'callback' => array( $this, 'get_list_tables_indexs' ),
33 - 'permission_callback' => '__return_true',
37 + 'permission_callback' => array( $this, 'check_permission' ),
34 38 ),
35 39 ),
36 - 'clean-tables' => array(
40 + 'clean-tables' => array(
37 41 array(
38 42 'methods' => WP_REST_Server::CREATABLE,
39 43 'callback' => array( $this, 'clean_tables' ),
40 - 'permission_callback' => '__return_true',
44 + 'permission_callback' => array( $this, 'check_permission' ),
41 45 ),
42 46 ),
43 - 'admin-notices' => array(
47 + /*'admin-notices' => array(
44 48 array(
45 49 'methods' => WP_REST_Server::ALLMETHODS,
46 50 'callback' => array( $this, 'admin_notices' ),
47 - 'permission_callback' => '__return_true',
51 + 'permission_callback' => array( $this, 'check_permission' ),
48 52 ),
53 + ),*/
54 + 'search-course' => array(
55 + array(
56 + 'methods' => WP_REST_Server::ALLMETHODS,
57 + 'callback' => array( $this, 'search_courses' ),
58 + 'permission_callback' => array( $this, 'check_permission' ),
59 + ),
49 60 ),
61 + 'search-user' => array(
62 + array(
63 + 'methods' => WP_REST_Server::ALLMETHODS,
64 + 'callback' => array( $this, 'search_users' ),
65 + 'permission_callback' => array( $this, 'check_permission' ),
66 + ),
67 + ),
68 + 'search-roles' => array(
69 + array(
70 + 'methods' => WP_REST_Server::READABLE,
71 + 'callback' => array( $this, 'search_roles' ),
72 + 'permission_callback' => array( $this, 'check_permission' ),
73 + ),
74 + ),
75 + 'assign-user-course' => array(
76 + array(
77 + 'methods' => WP_REST_Server::CREATABLE,
78 + 'callback' => array( $this, 'assign_courses_to_users' ),
79 + 'permission_callback' => array( $this, 'check_permission' ),
80 + ),
81 + ),
82 + 'unassign-user-course' => array(
83 + array(
84 + 'methods' => WP_REST_Server::CREATABLE,
85 + 'callback' => array( $this, 'unassign_user_from_course' ),
86 + 'permission_callback' => array( $this, 'check_permission' ),
87 + ),
88 + ),
50 89 );
51 90
52 91 parent::register_routes();
53 92 }
@@ -52,22 +91,32 @@
52 91 parent::register_routes();
53 92 }
54 93
55 94 /**
56 - * Create indexs.
95 + * Create create_indexes.
57 96 *
58 97 * @param WP_REST_Request $request .
59 98 *
60 99 * @return void
61 100 */
62 - public function create_indexs( WP_REST_Request $request ) {
101 + public function create_indexes( WP_REST_Request $request ) {
63 102 $response = new LP_REST_Response();
64 103 $lp_db = LP_Database::getInstance();
65 104
66 105 try {
67 - $tables = $request->get_param( 'tables' );
68 - $table = $request->get_param( 'table' );
69 - $table_keys = array();
106 + $tables_valid = [
107 + $lp_db->tb_lp_user_items,
108 + $lp_db->tb_lp_user_itemmeta,
109 + $lp_db->tb_lp_quiz_questions,
110 + $lp_db->tb_lp_question_answers,
111 + $lp_db->tb_lp_question_answermeta,
112 + $lp_db->tb_lp_order_items,
113 + $lp_db->tb_lp_order_itemmeta,
114 + $lp_db->tb_lp_sections,
115 + $lp_db->tb_lp_section_items,
116 + ];
117 + $table = $request->get_param( 'table' );
118 + $tables = $request->get_param( 'tables' );
70 119
71 120 $lp_db->wpdb->query( 'SET autocommit = 0' );
72 121
73 122 if ( empty( $tables ) ) {
@@ -75,11 +124,10 @@
75 124 } else {
76 125 $table_keys = array_keys( $tables );
77 126 }
78 127
79 - if ( empty( $table ) ) {
80 - $table = $lp_db->tb_lp_user_items;
81 - } elseif ( array_key_exists( $table, $table_keys ) ) {
128 + if ( ! array_key_exists( $table, $tables )
129 + || ! in_array( $table, $tables_valid ) ) {
82 130 throw new Exception( 'Table invalid!' );
83 131 }
84 132
85 133 // Create Indexs for a table.
@@ -128,10 +176,18 @@
128 176 public function get_list_tables_indexs( WP_REST_Request $request ) {
129 177 $response = new LP_REST_Response();
130 178 $lp_db = LP_Database::getInstance();
131 179
132 - $tables_indexs = array(
133 - $lp_db->tb_lp_user_items => array( 'user_id', 'item_id', 'item_type', 'status', 'ref_type', 'ref_id', 'parent_id' ),
180 + $tables_indexes = array(
181 + $lp_db->tb_lp_user_items => array(
182 + 'user_id',
183 + 'item_id',
184 + 'item_type',
185 + 'status',
186 + 'ref_type',
187 + 'ref_id',
188 + 'parent_id',
189 + ),
134 190 $lp_db->tb_lp_user_itemmeta => array( 'learnpress_user_item_id', 'meta_key', 'meta_value' ),
135 191 $lp_db->tb_lp_quiz_questions => array( 'quiz_id', 'question_id' ),
136 192 $lp_db->tb_lp_question_answers => array( 'question_id' ),
137 193 $lp_db->tb_lp_question_answermeta => '',
@@ -140,9 +196,9 @@
140 196 $lp_db->tb_lp_sections => array( 'section_course_id' ),
141 197 $lp_db->tb_lp_section_items => '',
142 198 );
143 199
144 - $response->data->tables = $tables_indexs;
200 + $response->data->tables = $tables_indexes;
145 201 $response->data->table = $lp_db->tb_lp_user_items;
146 202 $response->status = 'success';
147 203
148 204 wp_send_json( $response );
@@ -188,92 +244,331 @@
188 244 wp_send_json( $response );
189 245 }
190 246
191 247 /**
192 - * Show admin notices.
248 + * Search courses by title
193 249 *
194 250 * @param WP_REST_Request $request
195 251 *
196 - * @return void
197 - * @since 4.1.7.3.2
198 - * @version 1.0.0
252 + * @return LP_REST_Response
253 + * @since 4.2.5
254 + * @version 1.0.2
199 255 */
200 - public function admin_notices( WP_REST_Request $request ) {
256 + public function search_courses( WP_REST_Request $request ): LP_REST_Response {
257 + ini_set( 'max_execution_time', HOUR_IN_SECONDS );
258 +
201 259 $response = new LP_REST_Response();
202 - $content = '';
260 + try {
261 + $params = $request->get_params();
262 + $ids_str = LP_Helper::sanitize_params_submitted( $params['ids'] ?? '' );
263 + //$not_ids_str = LP_Helper::sanitize_params_submitted( $params['not_ids'] ?? '' );
264 + $not_ids_str = LP_Helper::sanitize_params_submitted( $params['id_not_in'] ?? '' );
265 + $current_ids = (array) LP_Helper::sanitize_params_submitted( $params['current_ids'] ?? [] );
266 + $total_rows = 0;
267 + $filter = new CourseJsonFilter();
268 + $filter->limit = 20;
269 + $filter->only_fields = [ 'ID', 'post_title' ];
270 + $filter->post_status = [ 'publish' ];
271 + $filter->post_title = LP_Helper::sanitize_params_submitted( $params['search'] ?? '' );
272 + $filter->page = LP_Helper::sanitize_params_submitted( $params['paged'] ?? 1, 'int' );
203 273
274 + if ( ! empty( $ids_str ) ) {
275 + $filter->ids = explode( ',', $ids_str );
276 + }
277 +
278 + if ( ! empty( $not_ids_str ) ) {
279 + $not_ids = explode( ',', $not_ids_str );
280 + $not_ids = array_map( 'absint', $not_ids );
281 + $not_ids = implode( ',', $not_ids );
282 + $filter->where[] = "AND ID NOT IN ({$not_ids})";
283 + }
284 +
285 + // Get all courses.
286 + $courses = Courses::get_list_courses( $filter, $total_rows );
287 +
288 + // Get selected courses.
289 + $courses_current = [];
290 + if ( ! empty( $current_ids ) ) {
291 + $current_ids = array_map( 'absint', $current_ids );
292 + $filter_current_ids = new LP_Course_Filter();
293 + $filter_current_ids->limit = -1;
294 + $filter_current_ids->only_fields = [ 'ID', 'post_title' ];
295 + $filter->post_status = [ 'publish' ];
296 + $filter_current_ids->post_ids = $current_ids;
297 + $courses_current = Courses::get_courses( $filter_current_ids );
298 + }
299 +
300 + $check_ids = [];
301 + $courses_rs = [];
302 + $courses_data = array_merge( $courses_current, $courses );
303 + foreach ( $courses_data as $course ) {
304 + if ( ! in_array( $course->ID, $check_ids ) ) {
305 + $courses_rs[] = $course;
306 + $check_ids[] = $course->ID;
307 + }
308 + }
309 + $response->data->courses = $courses_rs;
310 + $response->data->total_pages = LP_Database::get_total_pages( $filter->limit, $total_rows );
311 + $response->status = 'success';
312 + } catch ( Throwable $e ) {
313 + error_log( __METHOD__ . ': ' . $e->getMessage() );
314 + }
315 +
316 + ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
317 + return $response;
318 + }
319 +
320 + /**
321 + * Search user by name or email
322 + *
323 + * @param WP_REST_Request $request
324 + *
325 + * @return LP_REST_Response
326 + * @since 4.2.5
327 + * @version 1.0.2
328 + */
329 + public function search_users( WP_REST_Request $request ): LP_REST_Response {
330 + ini_set( 'max_execution_time', HOUR_IN_SECONDS );
331 +
332 + $response = new LP_REST_Response();
204 333 try {
205 - $params = $request->get_params();
206 - $admin_notices = $_SESSION['lp_admin_notices_dismiss'] ?? [];
207 - $lp_beta_version_info = LP_Admin_Notice::check_lp_beta_version();
334 + $params = $request->get_params();
335 + $search_string = LP_Helper::sanitize_params_submitted( $params['search'] ?? '' );
336 + $current_ids = LP_Helper::sanitize_params_submitted( $params['current_ids'] ?? '' );
337 + $number = LP_Helper::sanitize_params_submitted( $params['number'] ?? 20 );
338 + $args_get_user = array(
339 + 'search_columns' => array(
340 + 'user_login',
341 + 'user_nicename',
342 + 'user_email',
343 + ),
344 + 'number' => $number,
345 + 'fields' => array( 'ID', 'display_name', 'user_login', 'user_email' ),
346 + );
208 347
209 - if ( isset( $params['dismiss'] ) ) {
210 - if ( $lp_beta_version_info ) {
211 - // Store version of LP beta to session.
212 - $_SESSION['lp_beta_version'] = $lp_beta_version_info['version'] ?? 0;
348 + if ( ! empty( $search_string ) ) {
349 + $args_get_user['search'] = "*{$search_string}*";
350 + }
351 +
352 + $role_in = sanitize_text_field( $params['role_in'] ?? '' );
353 + if ( ! empty( $role_in ) ) {
354 + $args_get_user['role__in'] = explode( ',', $role_in );
355 + }
356 +
357 + $id_not_in = sanitize_text_field( $params['id_not_in'] ?? '' );
358 + if ( ! empty( $id_not_in ) ) {
359 + $args_get_user['exclude'] = explode( ',', $id_not_in );
360 + }
361 +
362 + // Get only users selected.
363 + $users_selected = [];
364 + $total_selected = 0;
365 + if ( ! empty( $current_ids ) ) {
366 + if ( ! is_array( $current_ids ) ) {
367 + $current_ids_array = explode( ',', $current_ids );
368 + } else {
369 + $current_ids_array = $current_ids;
213 370 }
214 - $admin_notices[ $params['dismiss'] ] = $params['dismiss'];
215 - $_SESSION['lp_admin_notices_dismiss'] = $admin_notices;
216 - $response->message = __( 'Dismissed!', 'learnpress' );
217 - } else {
218 - $show_notice_lp_beta_version = false;
219 - /**
220 - * Check if LP beta version is not dismissed or dismissed version lower than current version, will bet to so
221 - */
222 - if ( $lp_beta_version_info && ! isset( $_GET['tab'] ) &&
223 - ( ! isset( $_SESSION['lp_beta_version'] ) || version_compare( $_SESSION['lp_beta_version'], $lp_beta_version_info['version'], '<' ) ) ) {
224 - $show_notice_lp_beta_version = true;
371 + $args_get_user_current = array(
372 + 'include' => $current_ids_array,
373 + 'fields' => array( 'ID', 'display_name', 'user_login', 'user_email' ),
374 + );
375 + $users_selected_query = new WP_User_Query( $args_get_user_current );
376 + $users_selected = $users_selected_query->get_results();
377 + $total_selected = $users_selected_query->get_total() ?? 0;
378 + }
379 +
380 + $args_get_user = apply_filters( 'learn-press/rest-admin-tools/args-search-users', $args_get_user );
381 +
382 + // Get list users for search.
383 + $args_get_user['count_total'] = true;
384 + $users_search_query = new WP_User_Query( $args_get_user );
385 + $users_search = $users_search_query->get_results() ?? [];
386 + $total_search = $users_search_query->get_total() ?? 0;
387 + $users = array_merge( $users_selected, $users_search );
388 +
389 + $response->data->users = $users;
390 + $total = $total_selected + $total_search;
391 + $response->data->total_pages = LP_Database::get_total_pages( $number, $total );
392 + $response->status = 'success';
393 + } catch ( Throwable $e ) {
394 + error_log( __METHOD__ . ': ' . $e->getMessage() );
395 + }
396 +
397 + ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
398 + return $response;
399 + }
400 +
401 + /**
402 + * Search roles
403 + *
404 + * @param WP_REST_Request $request
405 + *
406 + * @return LP_REST_Response
407 + */
408 + public function search_roles( WP_REST_Request $request ): LP_REST_Response {
409 + $response = new LP_REST_Response();
410 + try {
411 + global $wp_roles;
412 + $data = [];
413 + $roles = $wp_roles->get_names();
414 + foreach ( $roles as $key => $value ) {
415 + $data[] = array(
416 + 'slug' => $key,
417 + 'name' => $value,
418 + );
419 + }
420 + $response->data = $data;
421 + $response->status = 'success';
422 + } catch ( Throwable $e ) {
423 + error_log( $e->getMessage() );
424 + }
425 +
426 + return $response;
427 + }
428 +
429 + /**
430 + * Enroll users to courses
431 + *
432 + * @param WP_REST_Request $request
433 + *
434 + * @return LP_REST_Response
435 + * @since 4.2.5
436 + * @version 1.0.1
437 + */
438 + public function assign_courses_to_users( WP_REST_Request $request ): LP_REST_Response {
439 + $response = new LP_REST_Response();
440 +
441 + try {
442 + $params = $request->get_params();
443 + $data = $params['data'] ?? [];
444 + $page = $params['page'] ?? 1;
445 + $total_page = $params['totalPage'] ?? 1;
446 +
447 + if ( ! is_array( $data ) ) {
448 + throw new Exception( 'Data assign is invalid' );
449 + }
450 +
451 + if ( empty( $data ) ) {
452 + throw new Exception( 'Please choose User and Course you want to Assign' );
453 + }
454 +
455 + foreach ( $data as $user_course ) {
456 + $user_id = $user_course['user_id'] ?? 0;
457 + $course_id = $user_course['course_id'] ?? 0;
458 + if ( ! $user_id || ! $course_id ) {
459 + throw new Exception( __( 'User or Course is invalid', 'learnpress' ) );
225 460 }
226 461
227 - $rules = apply_filters(
228 - 'learn-press/admin-notices',
229 - [
230 - // Check wp_remote call success.
231 - 'check_wp_remote' => [
232 - 'template' => 'admin-notices/wp-remote.php',
233 - 'check' => LP_Admin_Ajax::check_wp_remote(),
234 - ],
235 - // Check name plugin base.
236 - 'check_plugin_base' => [
237 - 'template' => 'admin-notices/plugin-base.php',
238 - 'check' => LP_Admin_Notice::check_plugin_base(),
239 - ],
240 - // Show beta version of LP.
241 - 'lp-beta-version' => [
242 - 'template' => 'admin-notices/beta-version.php',
243 - 'check' => $show_notice_lp_beta_version,
244 - 'info' => $lp_beta_version_info,
245 - 'dismiss' => 1,
246 - ],
247 - // Show message needs upgrades database compatible with LP version current.
248 - 'lp-upgrade-db' => [
249 - 'template' => 'admin-notices/upgrade-db.php',
250 - 'check' => LP_Updater::instance()->check_lp_db_need_upgrade(),
251 - ],
252 - // Show message wrong permalink structure.
253 - 'lp-permalink' => [
254 - 'template' => 'admin-notices/permalink-wrong.php',
255 - 'check' => ! get_option( 'permalink_structure' ),
256 - ],
257 - // Show notice setup wizard.
258 - 'lp-setup-wizard' => [
259 - 'template' => 'admin-notices/setup-wizard.php',
260 - 'check' => ! get_option( 'learn_press_setup_wizard_completed', false ) && ! isset( $admin_notices['lp-setup-wizard'] ),
261 - 'dismiss' => 1,
262 - ],
263 - ]
462 + $can_handle = apply_filters(
463 + 'learn-press/assign-courses-to-users/can-handle',
464 + true,
465 + $user_id,
466 + $course_id
264 467 );
468 + if ( ! $can_handle ) {
469 + continue;
470 + }
265 471
266 - foreach ( $rules as $template_data ) {
267 - $content .= learn_press_admin_view( $template_data['template'] ?? '', [ 'data' => $template_data ], true, true );
472 + // Delete data user who already enrolled this course.
473 + LP_User_Items_DB::getInstance()->delete_user_items_old( $user_id, $course_id );
474 + // End
475 +
476 + // Insert new data user to user_item table.
477 + $user_course_new = new UserCourseModel();
478 + $user_course_new->user_id = $user_id;
479 + $user_course_new->item_id = $course_id;
480 + $user_course_new->item_type = LP_COURSE_CPT;
481 + $user_course_new->ref_type = '';
482 + $user_course_new->status = LP_COURSE_ENROLLED;
483 + $user_course_new->graduation = LP_COURSE_GRADUATION_IN_PROGRESS;
484 + $user_course_new->start_time = gmdate( LP_Datetime::$format, time() );
485 + $user_course_new->save();
486 + // End
487 +
488 + do_action( 'learn-press/assigned-course-to-user', $user_course_new );
489 + }
490 +
491 + if ( $page == $total_page ) {
492 + $response->status = 'finished';
493 + $response->data->percent = 100 . '%';
494 + } else {
495 + $response->status = 'success';
496 + $response->data->page = $page;
497 + $response->data->percent = ( $page / $total_page ) * 100 . '%';
498 + }
499 +
500 + $response->message = __( 'Assign users to courses successfully.', 'learnpress' );
501 + } catch ( Throwable $e ) {
502 + $response->message = $e->getMessage();
503 + }
504 +
505 + return $response;
506 + }
507 +
508 + /**
509 + * Enroll users to courses
510 + *
511 + * @param WP_REST_Request $request
512 + *
513 + * @return LP_REST_Response
514 + * @since 4.2.5.6
515 + * @version 1.0.0
516 + */
517 + public function unassign_user_from_course( WP_REST_Request $request ): LP_REST_Response {
518 + $response = new LP_REST_Response();
519 +
520 + try {
521 + $params = $request->get_params();
522 + $data = $params['data'] ?? [];
523 + $page = $params['page'] ?? 1;
524 + $total_page = $params['totalPage'] ?? 1;
525 +
526 + if ( ! is_array( $data ) ) {
527 + throw new Exception( 'Data assign is invalid' );
528 + }
529 +
530 + if ( empty( $data ) ) {
531 + throw new Exception( 'Please choose User and Course you want to Unassign' );
532 + }
533 +
534 + foreach ( $data as $user_course ) {
535 + $user_id = $user_course['user_id'] ?? 0;
536 + $course_id = $user_course['course_id'] ?? 0;
537 + if ( ! $user_id || ! $course_id ) {
538 + throw new Exception( __( 'User or Course is invalid', 'learnpress' ) );
268 539 }
540 +
541 + // Delete data user who already enrolled this course.
542 + LP_User_Items_DB::getInstance()->delete_user_items_old( $user_id, $course_id );
543 + // End
269 544 }
270 545
271 - $response->status = 'success';
272 - $response->data->content = $content;
273 - } catch ( Exception $e ) {
546 + if ( $page === $total_page ) {
547 + $response->status = 'finished';
548 + $response->data->percent = 100 . '%';
549 + } else {
550 + $response->status = 'success';
551 + $response->data->page = $page;
552 + $response->data->percent = number_format( ( $page / $total_page ) * 100, 2 ) . '%';
553 + }
554 +
555 + $response->message = __( 'Unassigned users from courses successfully.', 'learnpress' );
556 + } catch ( Throwable $e ) {
274 557 $response->message = $e->getMessage();
275 558 }
276 559
277 - wp_send_json( $response );
560 + return $response;
561 + }
562 +
563 + /**
564 + * Check permission for request.
565 + *
566 + * @return bool
567 + */
568 + public function check_permission( $request = null ): bool {
569 + $permission = current_user_can( ADMIN_ROLE );
570 + $permission = apply_filters( 'learn-press/api-admin-tools/permission', $permission, $request );
571 +
572 + return $permission;
278 573 }
279 574 }