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