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/admin/class-lp-admin.php +318 -269 4.1.6.9.44.4.8 View file →
@@ -1,14 +1,17 @@
1 1 <?php
2 2 /**
3 3 * @author ThimPress
4 4 * @package LearnPress/Admin/Classes
5 - * @version 1.0.1
5 + * @version 1.0.2
6 6 */
7 -if ( ! defined( 'ABSPATH' ) ) {
8 - exit; // Exit if accessed directly
9 -}
10 7
8 +use LearnPress\Background\LPBackgroundAjax;
9 +use LearnPress\Models\CourseModel;
10 +use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderCourseTemplate;
11 +
12 +defined( 'ABSPATH' ) || exit;
13 +
11 14 if ( ! class_exists( 'LP_Admin' ) ) {
12 15 /**
13 16 * Class LP_Admin
14 17 */
@@ -14,32 +17,31 @@
14 17 */
15 18 class LP_Admin {
16 19 protected static $instance;
17 20
18 - /**
19 - * @var array
20 - */
21 - protected $_static_pages = false;
21 + protected $pages = [];
22 22
23 23 /**
24 24 * Constructor
25 25 */
26 26 protected function __construct() {
27 + $this->pages = [
28 + 'courses' => __( 'Courses', 'learnpress' ),
29 + 'instructors' => __( 'Instructors', 'learnpress' ),
30 + 'single_instructor' => __( 'Single Instructors', 'learnpress' ),
31 + 'profile' => __( 'Profile', 'learnpress' ),
32 + 'checkout' => __( 'Checkout', 'learnpress' ),
33 + 'become_a_teacher' => __( 'Become an Instructor', 'learnpress' ),
34 + ];
27 35 $this->includes();
28 36 add_action( 'delete_user', array( $this, 'delete_user_data' ) );
29 - add_action( 'delete_user_form', array( $this, 'delete_user_form' ) );
30 - add_action( 'wp_ajax_learn_press_rated', array( $this, 'rated' ) );
31 - add_action( 'admin_notices', array( $this, 'notice_outdated_templates' ) );
32 - add_action( 'admin_notices', array( $this, 'notice_required_permalink' ) );
33 - add_action( 'admin_notices', array( $this, 'admin_notices' ), 1 );
34 - //add_action( 'admin_head', array( $this, 'admin_colors' ) );
35 - // add_action( 'admin_init', array( $this, 'admin_redirect' ) );
37 + //add_action( 'delete_user_form', array( $this, 'delete_user_form' ) );
38 + add_action( 'all_admin_notices', array( $this, 'admin_notices' ), - 1 );
36 39 add_action( 'admin_enqueue_scripts', array( $this, 'load_modal' ) );
37 -
38 40 add_filter( 'admin_body_class', array( $this, 'body_class' ) );
39 - add_filter( 'manage_users_custom_column', array( $this, 'users_custom_column' ), 10, 3 );
40 - add_filter( 'manage_pages_columns', array( $this, 'page_columns_head' ) );
41 - add_filter( 'manage_pages_custom_column', array( $this, 'page_columns_content' ), 10, 2 );
41 + //add_filter( 'manage_users_custom_column', array( $this, 'users_custom_column' ), 10, 3 );
42 + //add_filter( 'manage_pages_columns', array( $this, 'page_columns_head' ) );
43 + //add_filter( 'manage_pages_custom_column', array( $this, 'page_columns_content' ), 10, 2 );
42 44 add_filter( 'views_edit-page', array( $this, 'views_pages' ), 10 );
43 45 add_filter( 'views_users', array( $this, 'views_users' ), 10, 1 );
44 46 add_filter( 'user_row_actions', array( $this, 'user_row_actions' ), 10, 2 );
45 47 add_filter( 'get_pages', array( $this, 'add_empty_page' ), 1000, 2 );
@@ -49,9 +51,9 @@
49 51 LP_Request::register( 'lp-action', array( $this, 'filter_users' ) );
50 52
51 53 add_filter( 'learn-press/modal-search-items-args', array( $this, 'filter_modal_search' ) );
52 54
53 - add_filter(
55 + /*add_filter(
54 56 'learn-press/dismissed-notice-response',
55 57 array(
56 58 $this,
57 59 'on_dismissed_notice_response',
@@ -57,9 +59,9 @@
57 59 'on_dismissed_notice_response',
58 60 ),
59 61 10,
60 62 2
61 - );
63 + );*/
62 64
63 65 // get list items course of user | tungnx
64 66 add_action( 'pre_get_posts', array( $this, 'get_course_items_of_user_backend' ), 10 );
65 67 add_action( 'pre_get_posts', array( $this, 'get_pages_of_lp' ), 10 );
@@ -65,8 +67,28 @@
65 67 add_action( 'pre_get_posts', array( $this, 'get_pages_of_lp' ), 10 );
66 68
67 69 // Set link item course when edit on Backend | tungnx
68 70 add_filter( 'get_sample_permalink_html', array( $this, 'lp_course_set_link_item_backend' ), 10, 5 );
71 +
72 + // Add "Edit with Course Builder" button below title area for courses
73 + add_action( 'edit_form_after_title', array( $this, 'add_course_builder_button' ) );
74 +
75 + /*add_action(
76 + 'admin_init',
77 + function () {
78 + // From LP v4.2.3 temporary run create pages to add page instructors, single instructor for client upgrade LP.
79 + // After a long time, will remove this code.
80 + if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
81 + LP_Install::create_pages();
82 + }
83 + }
84 + );*/
85 +
86 + add_filter( 'users_list_table_query_args', [ $this, 'exclude_temp_users' ] );
87 +
88 + // Show label 'LearnPress Page' for page of LearnPress.
89 + //add_filter('post_states_html');
90 + add_filter( 'display_post_states', [ $this, 'show_label_page_type' ], 10, 2 );
69 91 }
70 92
71 93 /**
72 94 * @since 3.2.6
@@ -71,15 +93,16 @@
71 93 /**
72 94 * @since 3.2.6
73 95 */
74 96 public function load_modal() {
75 - if ( in_array( get_post_type(), array( LP_COURSE_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, LP_ORDER_CPT ) ) ) {
97 + // Now only add item(s) when create new Order is using.
98 + if ( in_array( get_post_type(), array( LP_ORDER_CPT ) ) ) {
76 99 LP_Modal_Search_Items::instance();
77 100 }
78 101
79 - if ( in_array( get_post_type(), array( LP_ORDER_CPT ) ) ) {
102 + /*if ( in_array( get_post_type(), array( LP_ORDER_CPT ) ) ) {
80 103 LP_Modal_Search_Users::instance();
81 - }
104 + }*/
82 105 }
83 106
84 107 /**
85 108 * @param $options
@@ -121,9 +144,9 @@
121 144 if ( $active_plugins ) {
122 145 if ( $search ) {
123 146 foreach ( $search as $k => $v ) {
124 147 if ( in_array( $k, $active_plugins ) ) {
125 - $count_activated ++;
148 + ++ $count_activated;
126 149 }
127 150 }
128 151 }
129 152 }
@@ -179,9 +202,9 @@
179 202 * @param int $id
180 203 *
181 204 * @return bool
182 205 */
183 - protected function _is_wc_page( $id ) {
206 + /*protected function _is_wc_page( $id ) {
184 207 if ( class_exists( 'WooCommerce' ) ) {
185 208 if ( ! class_exists( 'WC_Admin_Post_Types' ) ) {
186 209 include_once dirname( WC_PLUGIN_FILE ) . '/includes/admin/class-wc-admin-post-types.php';
187 210 }
@@ -206,11 +229,11 @@
206 229 }
207 230 }
208 231
209 232 return false;
210 - }
233 + }*/
211 234
212 - public function wc_add_display_post_states( $post_states, $post ) {
235 + /*public function wc_add_display_post_states( $post_states, $post ) {
213 236 if ( wc_get_page_id( 'shop' ) === $post->ID ) {
214 237 $post_states['wc_page_for_shop'] = __( 'Shop Page', 'learnpress' );
215 238 }
216 239
@@ -230,9 +253,9 @@
230 253 $post_states['wc_page_for_terms'] = __( 'Terms and Conditions Page', 'learnpress' );
231 254 }
232 255
233 256 return $post_states;
234 - }
257 + }*/
235 258
236 259 /**
237 260 * Check if a page is set for Paid Membership Pro.
238 261 *
@@ -239,9 +262,9 @@
239 262 * @param int $id
240 263 *
241 264 * @return bool|mixed
242 265 */
243 - protected function _is_pmpro_page( $id ) {
266 + /*protected function _is_pmpro_page( $id ) {
244 267 global $pmpro_pages;
245 268 if ( $pmpro_pages ) {
246 269 $pages = array(
247 270 'account' => __( 'Account', 'learnpress' ),
@@ -260,9 +283,9 @@
260 283 }
261 284 }
262 285
263 286 return false;
264 - }
287 + }*/
265 288
266 289 /**
267 290 * Check if a page is set for Paid Membership Pro.
268 291 *
@@ -269,9 +292,9 @@
269 292 * @param int $id
270 293 *
271 294 * @return bool|mixed
272 295 */
273 - protected function _is_bp_page( $id ) {
296 + /*protected function _is_bp_page( $id ) {
274 297 if ( function_exists( 'buddypress' ) ) {
275 298 $bp_pages = get_option( 'bp-pages' );
276 299 if ( ! $bp_pages ) {
277 300 return false;
@@ -291,56 +314,56 @@
291 314 }
292 315 }
293 316
294 317 return false;
295 - }
318 + }*/
296 319
297 320 /**
298 - * @param string $plugin
321 + * Get pages is publish set by LearnPress.
299 322 *
300 - * @return array|bool
323 + * @return array
301 324 */
302 - protected function _get_static_pages( $plugin = '' ) {
303 - if ( false === $this->_static_pages ) {
304 - $this->_static_pages = array(
305 - 'learnpress' => array(),
306 - 'WooCommerce' => array(),
307 - 'Paid Membership Pro' => array(),
308 - 'BuddyPress' => array(),
309 - );
325 + protected function _get_static_pages(): array {
326 + $static_pages = [];
327 + foreach ( $this->pages as $name => $title ) {
328 + $page_id = learn_press_get_page_id( $name );
310 329
311 - $all_pages = array(
312 - 'courses' => __( 'Courses', 'learnpress' ),
313 - 'profile' => __( 'Profile', 'learnpress' ),
314 - 'checkout' => __( 'Checkout', 'learnpress' ),
315 - 'become_a_teacher' => __( 'Become a Teacher', 'learnpress' ),
316 - );
330 + if ( $page_id && 'publish' === get_post_status( $page_id ) ) {
331 + $static_pages[ $page_id ] = $title;
332 + }
333 + }
317 334
318 - foreach ( $all_pages as $name => $title ) {
319 - $page_id = learn_press_get_page_id( $name );
335 + return $static_pages;
336 + }
320 337
321 - if ( $page_id && 'publish' === get_post_status( $page_id ) ) {
322 - $this->_static_pages['learnpress'][ $page_id ] = $title;
338 + /**
339 + * Show label LearnPress Page for pages set by LearnPress.
340 + *
341 + * @param array $post_states
342 + * @param WP_Post $post
343 + *
344 + * @return array
345 + * @since 4.3.2.6
346 + * @version 1.0.0
347 + */
348 + public function show_label_page_type( $post_states, $post ) {
349 + $post_type = get_post_type( $post );
350 + if ( $post_type !== 'page' ) {
351 + return $post_states;
352 + }
323 353
324 - $for_page = $this->_is_wc_page( $page_id );
325 - if ( $for_page ) {
326 - $this->_static_pages['WooCommerce'][ $page_id ] = $for_page;
327 - }
328 -
329 - $for_page = $this->_is_pmpro_page( $page_id );
330 - if ( $for_page ) {
331 - $this->_static_pages['Paid Membership Pro'][ $page_id ] = $for_page;
332 - }
333 -
334 - $for_page = $this->_is_bp_page( $page_id );
335 - if ( $for_page ) {
336 - $this->_static_pages['BuddyPress'][ $page_id ] = $for_page;
337 - }
338 - }
354 + $page_id_compare = $post->ID;
355 + foreach ( $this->_get_static_pages() as $page_id => $title ) {
356 + if ( $page_id == $page_id_compare ) {
357 + $post_states['lp_page'] = sprintf(
358 + '<span class="is-lp-page">%s</span>',
359 + 'LearnPress ' . $title . ' Page'
360 + );
361 + break;
339 362 }
340 363 }
341 364
342 - return $plugin ? ( ! empty( $this->_static_pages[ $plugin ] ) ? $this->_static_pages[ $plugin ] : false ) : $this->_static_pages;
365 + return $post_states;
343 366 }
344 367
345 368 /**
346 369 * Add new column to WP Pages manage to show what page is assigned to.
@@ -348,9 +371,9 @@
348 371 * @param array $columns
349 372 *
350 373 * @return array
351 374 */
352 - public function page_columns_head( $columns ) {
375 + /*public function page_columns_head( $columns ) {
353 376
354 377 $_columns = $columns;
355 378 $columns = array();
356 379
@@ -361,17 +384,17 @@
361 384 $columns[ $name ] = $text;
362 385 }
363 386
364 387 return $columns;
365 - }
388 + }*/
366 389
367 390 /**
368 391 * Display the page is assigned to LP Page.
369 392 *
370 393 * @param string $column_name
371 - * @param int $post
394 + * @param int $post
372 395 */
373 - public function page_columns_content( $column_name, $post ) {
396 + /*public function page_columns_content( $column_name, $post ) {
374 397 $pages = $this->_get_static_pages();
375 398 switch ( $column_name ) {
376 399 case 'lp-page':
377 400 if ( ! empty( $pages['learnpress'][ $post ] ) ) {
@@ -391,9 +414,9 @@
391 414 );
392 415 }
393 416 }
394 417 }
395 - }
418 + }*/
396 419
397 420 /**
398 421 * @param $actions
399 422 *
@@ -399,15 +422,13 @@
399 422 *
400 423 * @return mixed
401 424 */
402 425 public function views_pages( $actions ) {
403 - $this->_get_static_pages();
426 + $pages = $this->_get_static_pages();
404 427
405 - $pages = $this->_get_static_pages( 'learnpress' );
406 -
407 428 if ( $pages ) {
408 429 $text = sprintf( __( 'LearnPress Pages (%d)', 'learnpress' ), sizeof( $pages ) );
409 - if ( 'yes' !== LP_Request::get( 'lp-page' ) ) {
430 + if ( 'yes' !== LP_Request::get_param( 'lp-page' ) ) {
410 431 $actions['lp-page'] = sprintf(
411 432 '<a href="%s">%s</a>',
412 433 admin_url( 'edit.php?post_type=page&lp-page=yes' ),
413 434 $text
@@ -427,11 +448,15 @@
427 448 *
428 449 * @return mixed
429 450 */
430 451 public function get_pages_of_lp( $q ) {
431 - if ( 'page' == LP_Request::get( 'post_type' ) && 'yes' == LP_Request::get( 'lp-page' ) ) {
432 - $ids = $this->_get_static_pages( 'learnpress' );
452 + if ( ! is_admin() || ! $q->is_main_query() ) {
453 + return $q;
454 + }
433 455
456 + if ( 'page' == LP_Request::get_param( 'post_type' ) && 'yes' == LP_Request::get_param( 'lp-page' ) ) {
457 + $ids = $this->_get_static_pages();
458 +
434 459 if ( ! empty( $ids ) ) {
435 460 $ids = array_keys( $ids );
436 461 $q->set( 'post__in', $ids );
437 462 }
@@ -442,24 +467,27 @@
442 467
443 468 /**
444 469 * Add actions to users list
445 470 *
446 - * @param array $actions
471 + * @param array $actions
447 472 * @param WP_User $user
448 473 *
449 474 * @return mixed
450 475 */
451 476 public function user_row_actions( $actions, $user ) {
452 - $pending_request = LP_User_Factory::get_pending_requests();
453 - if ( LP_Request::get_string( 'lp-action' ) == 'pending-request' && $pending_request ) {
477 + $pending_request = self::get_pending_requests();
478 + if ( LP_Request::get_param( 'lp-action' ) == 'pending-request' && $pending_request ) {
454 479 $actions = array();
480 + $nonce = 'nonce=' . wp_create_nonce( 'lp-action-permit-role-teacher' );
455 481 if ( in_array( $user->ID, $pending_request ) ) {
456 482 $actions['accept'] = sprintf(
457 - '<a href="' . admin_url( 'users.php?lp-action=accept-request&user_id=' . $user->ID ) . '">%s</a>',
483 + '<a href="%s">%s</a>',
484 + admin_url( "users.php?lp-action=accept-request&user_id={$user->ID}&{$nonce}" ),
458 485 _x( 'Accept', 'pending-request', 'learnpress' )
459 486 );
460 487 $actions['delete deny'] = sprintf(
461 - '<a class="submitdelete" href="' . admin_url( 'users.php?lp-action=deny-request&user_id=' . $user->ID ) . '">%s</a>',
488 + '<a class="submitdelete" href="%s">%s</a>',
489 + admin_url( "users.php?lp-action=deny-request&user_id={$user->ID}&{$nonce}" ),
462 490 _x( 'Deny', 'pending-request', 'learnpress' )
463 491 );
464 492 }
465 493 }
@@ -466,9 +494,38 @@
466 494
467 495 return $actions;
468 496 }
469 497
498 + public function exclude_temp_users( $args ) {
499 + if ( LP_Request::get_param( 'lp-action' ) == 'pending-request' ) {
500 + $args['include'] = self::get_pending_requests();
501 + }
502 +
503 + return $args;
504 + }
505 +
470 506 /**
507 + * Get pending requests be come a Teacher.
508 + *
509 + * @return array
510 + */
511 + public static function get_pending_requests() {
512 + global $wpdb;
513 + $query = $wpdb->prepare(
514 + "
515 + SELECT ID
516 + FROM {$wpdb->users} u
517 + INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s
518 + WHERE um.meta_value = %s
519 + ",
520 + '_requested_become_teacher',
521 + 'yes'
522 + );
523 +
524 + return $wpdb->get_col( $query );
525 + }
526 +
527 + /**
471 528 * Filter user by custom param
472 529 *
473 530 * @param string $action
474 531 */
@@ -476,38 +533,59 @@
476 533 if ( ! current_user_can( 'administrator' ) ) {
477 534 return;
478 535 }
479 536
480 - $user_id = LP_Request::get_int( 'user_id' );
537 + $user_id = LP_Request::get_param( 'user_id', 'int' );
538 + if ( ! $user_id || ! get_user_by( 'id', $user_id ) ) {
539 + return;
540 + }
481 541
482 - if ( ! $user_id || ! get_user_by( 'id', $user_id ) ) {
542 + $nonce = LP_Request::get_param( 'nonce' );
543 + if ( ! wp_verify_nonce( $nonce, 'lp-action-permit-role-teacher' ) ) {
483 544 return;
484 545 }
485 546
486 547 $user_data = get_userdata( $user_id );
548 + if ( in_array( $action, array( 'accept-request', 'deny-request' ) ) ) {
549 + delete_user_meta( $user_id, '_requested_become_teacher' );
550 + }
487 551
488 - if ( in_array( $action, array( 'accept-request', 'deny-request' ) ) ) {
552 + switch ( $action ) {
553 + case 'accept-request':
554 + $be_teacher = new WP_User( $user_id );
555 + $be_teacher->set_role( LP_TEACHER_ROLE );
489 556
490 - delete_user_meta( $user_id, '_requested_become_teacher' );
557 + /**
558 + * Send email to user when admin accept user become a teacher
559 + * @use SendEmailAjax::send_mail_become_a_teacher_accept
560 + */
561 + $data_send = [
562 + 'params' => [ $user_data->user_email ],
563 + 'lp-load-ajax' => 'send_mail_become_a_teacher_accept',
564 + ];
565 + LPBackgroundAjax::handle( $data_send );
491 566
492 - switch ( $action ) {
493 - case 'accept-request':
494 - $be_teacher = new WP_User( $user_id );
495 - $be_teacher->set_role( LP_TEACHER_ROLE );
567 + do_action( 'learn-press/user-become-a-teacher-accept', $user_data->user_email );
568 + wp_redirect( admin_url( 'users.php?lp-action=accepted-request&user_id=' . $user_id ) );
569 + exit();
570 + case 'deny-request':
571 + /**
572 + * Send email to user when admin accept user become a teacher
573 + * @use SendEmailAjax::send_mail_become_a_teacher_deny
574 + */
575 + $data_send = [
576 + 'params' => [ $user_data->user_email ],
577 + 'lp-load-ajax' => 'send_mail_become_a_teacher_deny',
578 + ];
579 + LPBackgroundAjax::handle( $data_send );
496 580
497 - do_action( 'learn-press/user-become-a-teacher-accept', $user_data->user_email );
498 - wp_redirect( admin_url( 'users.php?lp-action=accepted-request&user_id=' . $user_id ) );
499 - exit();
500 - case 'deny-request':
501 - do_action( 'learn-press/user-become-a-teacher-deny', $user_data->user_email );
502 - wp_redirect( admin_url( 'users.php?lp-action=denied-request&user_id=' . $user_id ) );
503 - exit();
504 - }
581 + do_action( 'learn-press/user-become-a-teacher-deny', $user_data->user_email );
582 + wp_redirect( admin_url( 'users.php?lp-action=denied-request&user_id=' . $user_id ) );
583 + exit();
505 584 }
506 585 }
507 586
508 587 public function users_custom_column( $content, $column_name, $user_id ) {
509 -
510 588 }
511 589
512 590 /**
513 591 * Add new view to users views for filtering user by "pending request" of "become a teacher".
@@ -516,12 +594,12 @@
516 594 *
517 595 * @return mixed
518 596 */
519 597 public function views_users( $views ) {
520 - $pending_request = LP_User_Factory::get_pending_requests();
598 + $pending_request = self::get_pending_requests();
521 599
522 600 if ( $pending_request ) {
523 - if ( LP_Request::get_string( 'lp-action' ) == 'pending-request' ) {
601 + if ( LP_Request::get_param( 'lp-action' ) == 'pending-request' ) {
524 602 $class = ' class="current"';
525 603 foreach ( $views as $k => $view ) {
526 604 $views[ $k ] = preg_replace( '!class="current"!', '', $view );
527 605 }
@@ -540,62 +618,8 @@
540 618 return $views;
541 619 }
542 620
543 621 /**
544 - * Display admin notices
545 - */
546 - public function admin_notices() {
547 - if ( ! current_user_can( ADMIN_ROLE ) ) {
548 - return;
549 - }
550 -
551 - if ( ! get_option( 'learn_press_setup_wizard_completed', false ) ) {
552 - learn_press_admin_view( 'setup/notice-setup' );
553 - }
554 -
555 - $action = LP_Request::get( 'lp-action' );
556 - $user_id = LP_Request::get_int( 'user_id' );
557 -
558 - if ( ( in_array(
559 - $action,
560 - array( 'accepted-request', 'denied-request' )
561 - ) ) && ( $user_id ) && get_user_by(
562 - 'id',
563 - $user_id
564 - ) ) {
565 - if ( ! current_user_can( 'promote_user', $user_id ) ) {
566 - wp_die( __( 'Sorry, you are not allowed to edit this user.', 'learnpress' ) );
567 - }
568 - ?>
569 -
570 - <div class="updated notice">
571 - <p>
572 - <?php
573 - echo sprintf(
574 - __( 'User has %s to become a teacher.', 'learnpress' ),
575 - $action == 'accepted-request' ? 'accepted' : 'denied'
576 - );
577 - ?>
578 - </p>
579 - </div>
580 -
581 - <?php
582 - }
583 - }
584 -
585 - /**
586 - * Redirect to setup page if we have just activated LP
587 - * @depecated 4.1.6.4
588 - */
589 - /*public function admin_redirect() {
590 - if ( 'yes' === get_transient( 'lp_activation_redirect' ) && current_user_can( 'install_plugins' ) ) {
591 - delete_transient( 'lp_activation_redirect' );
592 -
593 - exit( wp_safe_redirect( admin_url( 'index.php?page=lp-setup' ) ) );
594 - }
595 - }*/
596 -
597 - /**
598 622 * Custom admin body classes.
599 623 *
600 624 * @param array $classes
601 625 *
@@ -619,51 +643,49 @@
619 643
620 644 return $classes;
621 645 }
622 646
623 - public function notice_required_permalink() {
624 - if ( current_user_can( 'manage_options' ) ) {
625 - if ( ! get_option( 'permalink_structure' ) ) {
626 - ?>
627 - <div class="notice notice-error">
628 - <p>
629 - <?php
630 - echo sprintf(
631 - 'LearnPress requires permalink option <strong>Post name</strong> is enabled. Please enable it <a href="%s">here</a> to ensure that all functions work properly.',
632 - admin_url( 'options-permalink.php' )
633 - )
634 - ?>
635 - </p>
636 - </div>
637 - <?php
638 - }
639 - }
640 - }
641 -
642 647 /**
643 - * Notices outdated templates.
648 + * Display notices on Backend.
644 649 */
645 - public function notice_outdated_templates() {
646 - if ( current_user_can( 'manage_options' ) ) {
647 - $page = LP_Helper::sanitize_params_submitted( $_REQUEST['page'] ?? '' );
648 - $tab = LP_Helper::sanitize_params_submitted( $_REQUEST['tab'] ?? '' );
649 -
650 - if ( $page == 'learn-press-tools' && $tab == 'templates' ) {
650 + public function admin_notices() {
651 + if ( function_exists( 'get_current_screen' ) ) {
652 + $wp_screen = get_current_screen();
653 + // Not run on course edit screen, it slows, can affect performance edit course.
654 + if ( $wp_screen->id === LP_COURSE_CPT ) {
651 655 return;
652 656 }
657 + }
653 658
659 + // Show template file templates override.
660 + $page = LP_Request::get_param( 'page' );
661 + $tab = LP_Request::get_param( 'tab' );
662 + if ( $page == 'learn-press-tools' && $tab == 'templates' ) {
654 663 if ( LP_Outdated_Template_Helper::detect_outdated_template() ) {
655 664 learn_press_admin_view( 'html-admin-notice-templates' );
656 665 }
657 666 }
658 - }
659 667
660 - /**
661 - * Update option data user rated.
662 - */
663 - public function rated() {
664 - update_option( 'learn_press_message_user_rated', 'yes' );
665 - die();
668 + // Request accept/denied user can become a teacher.
669 + $action_become_teacher = LP_Request::get_param( 'lp-action' );
670 + $user_id = LP_Request::get_param( 'user_id', 0, 'int' );
671 + $type_action_become_teacher = array( 'accepted-request', 'denied-request' );
672 + if ( in_array( $action_become_teacher, $type_action_become_teacher ) && $user_id && get_user_by( 'id', $user_id ) ) {
673 + ?>
674 + <div class="updated notice">
675 + <p>
676 + <?php
677 + echo sprintf(
678 + __( 'A user has %s to become a teacher.', 'learnpress' ),
679 + $action_become_teacher == 'accepted-request' ? 'accepted' : 'denied'
680 + );
681 + ?>
682 + </p>
683 + </div>
684 + <?php
685 + }
686 +
687 + learn_press_admin_view( 'admin-notices.php', [], true );
666 688 }
667 689
668 690 /**
669 691 * Admin footer add review.
@@ -682,9 +704,9 @@
682 704 ) ) {
683 705 if ( ! get_option( 'learn_press_message_user_rated' ) ) {
684 706 $footer_text = sprintf(
685 707 __(
686 - 'If you like <strong>LearnPress</strong> please leave us a %1$s&#9733;&#9733;&#9733;&#9733;&#9733;%2$s rating. A huge thanks from LearnPress team for your generous.',
708 + 'If you like <strong>LearnPress</strong> please leave us a %1$s&#9733;&#9733;&#9733;&#9733;&#9733;%2$s rating. A huge thanks from the LearnPress team for your generosity.',
687 709 'learnpress'
688 710 ),
689 711 '<a href="https://wordpress.org/support/plugin/learnpress/reviews/?filter=5#postform" target="_blank" class="lp-rating-link" data-rated="' . esc_attr__(
690 712 'Thanks :)',
@@ -691,30 +713,8 @@
691 713 'learnpress'
692 714 ) . '">',
693 715 '</a>'
694 716 );
695 -
696 - ob_start();
697 - ?>
698 -
699 - <script>
700 - jQuery(function ($) {
701 - var $ratingLink = $('a.lp-rating-link').click(function (e) {
702 - $.ajax({
703 - url: '<?php echo admin_url( 'admin-ajax.php' ); ?>',
704 - data: {
705 - action: 'learn_press_rated'
706 - },
707 - success: function () {
708 - $ratingLink.parent().html($ratingLink.data('rated'))
709 - }
710 - })
711 - })
712 - })
713 - </script>
714 -
715 - <?php
716 - echo ob_get_clean();
717 717 }
718 718 }
719 719
720 720 return $footer_text;
@@ -719,11 +719,11 @@
719 719
720 720 return $footer_text;
721 721 }
722 722
723 - function delete_user_form() {
723 + /*function delete_user_form() {
724 724 // What should be displayed here?
725 - }
725 + }*/
726 726
727 727 /**
728 728 * Delete records related user being deleted in other tables
729 729 *
@@ -735,15 +735,16 @@
735 735
736 736 /**
737 737 * Send data to join newsletter or dismiss.
738 738 *
739 - * @param array $data
739 + * @param array $data
740 740 * @param string $notice
741 741 *
742 742 * @return array
743 743 * @since 3.0.10
744 + * @deprecated 4.2.3.1
744 745 */
745 - public function on_dismissed_notice_response( $data, $notice ) {
746 + /*public function on_dismissed_notice_response( $data, $notice ) {
746 747 switch ( $notice ) {
747 748 case 'skip-setup-wizard':
748 749 delete_option( 'learn_press_install' );
749 750 break;
@@ -754,9 +755,9 @@
754 755 }
755 756
756 757 $user = learn_press_get_current_user();
757 758 if ( ! $user || $user->get_email() == '' ) {
758 - $data['error'] = __( 'Fail while joining newsletter! Please try again!', 'learnpress' );
759 + $data['error'] = __( 'Failed while joining the newsletter! Please try again!', 'learnpress' );
759 760 }
760 761
761 762 $url = 'https://thimpress.com/mailster/subscribe';
762 763 $response = wp_remote_post(
@@ -783,9 +784,9 @@
783 784 $error_message = $response->get_error_message();
784 785 $data['message'] = __( 'Something went wrong: ', 'learnpress' ) . $error_message;
785 786 } else {
786 787 $data['message'] = __(
787 - 'Thank you for subscribing! Please check and click the confirmation link from the email we\'ve just sent to your mail box.',
788 + 'Thank you for subscribing! Please check and click the confirmation link from the email that we\'ve just sent to your inbox.',
788 789 'learnpress'
789 790 );
790 791 }
791 792 }
@@ -790,9 +791,9 @@
790 791 }
791 792 }
792 793
793 794 return $data;
794 - }
795 + }*/
795 796
796 797 /**
797 798 * Include all classes and functions used for admin
798 799 */
@@ -799,10 +800,18 @@
799 800 public function includes() {
800 801 // Common function used in admin
801 802 include_once 'lp-admin-functions.php';
802 803 include_once 'lp-admin-actions.php';
803 - require_once LP_PLUGIN_PATH . 'inc/background-process/class-lp-background-query-items.php';
804 804 include_once 'class-lp-admin-assets.php';
805 + LP_Admin_Assets::instance();
806 + // For MCP
807 + if ( learn_press_is_mcp_available() ) {
808 + include_once 'class-lp-admin-mcp-api-keys.php';
809 + LP_Admin_MCP_API_Keys::instance();
810 + }
811 + // End MCP
812 + include_once 'class-lp-admin-webhooks.php';
813 + LP_Admin_Webhooks::instance();
805 814 include_once 'class-lp-admin-dashboard.php';
806 815 // include_once 'class-lp-admin-tools.php';
807 816 include_once 'class-lp-admin-ajax.php';
808 817 include_once 'editor/class-lp-admin-editor.php';
@@ -807,19 +816,19 @@
807 816 include_once 'class-lp-admin-ajax.php';
808 817 include_once 'editor/class-lp-admin-editor.php';
809 818 include_once 'class-lp-admin-menu.php';
810 819 include_once 'helpers/class-lp-outdated-template-helper.php';
811 - include_once 'helpers/class-lp-plugins-helper.php';
812 820 include_once 'class-lp-modal-search-items.php';
813 - include_once 'class-lp-modal-search-users.php';
821 + //include_once 'class-lp-modal-search-users.php';
814 822 include_once 'class-lp-setup-wizard.php';
815 823 // include_once 'class-lp-updater.php';
816 - include_once 'class-lp-install-sample-data.php';
817 - include_once 'class-lp-reset-data.php';
824 + // include_once 'class-lp-install-sample-data.php'; // Replaced by LearnPress\Ajax\SampleDataAJAX.
825 + // include_once 'class-lp-reset-data.php'; // Deprecated: replaced by CourseToolsAjax::reset_progress_items_course.
818 826 include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/course/settings.php';
827 + include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/course/class-lp-meta-box-course-offline.php';
819 828 include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/quiz/settings.php';
820 829 include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/lesson/settings.php';
821 - include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/question/settings.php';
830 + //include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/question/settings.php';
822 831 }
823 832
824 833 /**
825 834 * Get courses, item's courses on Backend page post_type
@@ -830,9 +839,9 @@
830 839 if ( ! $query->is_main_query() ) {
831 840 return;
832 841 }
833 842
834 - global $post_type, $pagenow;
843 + /*global $post_type, $pagenow;
835 844
836 845 if ( current_user_can( ADMIN_ROLE ) ) {
837 846 return;
838 847 }
@@ -847,25 +856,26 @@
847 856 );
848 857
849 858 if ( ! in_array( $post_type, $post_type_valid ) ) {
850 859 return;
851 - }
860 + }*/
852 861
853 862 // $query->set( 'author', get_current_user_id() );
854 863
855 - $query = apply_filters( 'learnpress/get-post-type-lp-on-backend', $query );
864 + // Hook only Co-instructor using.
865 + return apply_filters( 'learnpress/get-post-type-lp-on-backend', $query );
856 866
857 867 //add_filter( 'views_edit-' . $post_type . '', '_learn_press_restrict_view_items', 10 );
858 - remove_filter( 'pre_get_posts', array( $this, 'get_course_items_of_user_backend' ), 10 );
868 + //remove_filter( 'pre_get_posts', array( $this, 'get_course_items_of_user_backend' ), 10 );
859 869 }
860 870
861 871 /**
862 872 * Set link item of course when edit item on Backend
863 873 *
864 - * @param string $post_link
865 - * @param int $post_id
866 - * @param string $new_title
867 - * @param string $new_slug
874 + * @param string $post_link
875 + * @param int $post_id
876 + * @param string $new_title
877 + * @param string $new_slug
868 878 * @param WP_Post|null $post
869 879 *
870 880 * @return string
871 881 * @author tungnx
@@ -872,53 +882,92 @@
872 882 * @since 3.2.7.5
873 883 * @version 4.0.1
874 884 */
875 885 public function lp_course_set_link_item_backend( $post_link = '', $post_id = 0, $new_title = '', $new_slug = '', $post = null ) {
876 - if ( ! in_array( $post->post_type, learn_press_get_course_item_types() ) ) {
877 - return $post_link;
878 - }
879 -
880 886 try {
881 - $course_id_of_item = LP_Course_DB::getInstance()->get_course_by_item_id( $post->ID );
887 + if ( in_array( $post->post_type, CourseModel::item_types_support() ) ) {
888 + $course_id_of_item = LP_Course_DB::getInstance()->get_course_by_item_id( $post->ID );
889 + if ( $course_id_of_item ) {
890 + $course = learn_press_get_course( $course_id_of_item );
891 + if ( $course ) {
892 + $link_item = urldecode( $course->get_item_link( $post->ID ) );
893 + $post_slug = $post->post_name;
894 + $link_item_edit_slug = preg_replace( '/' . $post_slug . '$/', '', $link_item );
882 895
883 - if ( $course_id_of_item ) {
884 - $course = learn_press_get_course( $course_id_of_item );
896 + // For update new slug
897 + if ( $new_slug ) {
898 + $post_slug = $new_slug;
899 + }
900 + $post_slug = urldecode( $post_slug );
885 901
886 - if ( $course ) {
887 - $link_item = $course->get_item_link( $post->ID );
902 + $slug_arr = explode( '/', $link_item_edit_slug );
903 + $count_slug = count( $slug_arr );
904 + unset( $slug_arr[ $count_slug - 2 ] );
905 + $link_item_edit_slug = implode( '/', $slug_arr );
888 906
889 - $post_slug = $post->post_name;
890 - $link_item_edit_slug = preg_replace( '/' . $post_slug . '$/', '', $link_item );
891 -
892 - // For update new slug
893 - if ( $new_slug ) {
894 - $post_slug = $new_slug;
907 + $post_link = '<strong>Permalink: </strong>';
908 + $post_link .= '<span id="sample-permalink">';
909 + $post_link .= '<a href="' . $link_item . '">' . $link_item_edit_slug . '<span id="editable-post-name">' . $post_slug . '</span>/</a>';
910 + $post_link .= '</span>';
911 + $post_link .= '&lrm;<span id="edit-slug-buttons">';
912 + $post_link .= '<button type="button" class="edit-slug button button-small hide-if-no-js" aria-label="Edit permalink">Edit</button>';
913 + $post_link .= '</span>';
914 + $post_link .= '<span id="editable-post-name-full">' . $post_slug . '</span>';
895 915 }
896 -
897 - $post_link = '<strong>Permalink: </strong>';
898 - $post_link .= '<span id="sample-permalink">';
899 - $post_link .= '<a href="' . $link_item . '">' . $link_item_edit_slug . '<span id="editable-post-name">' . $post_slug . '</span>/</a>';
900 - $post_link .= '</span>';
901 - $post_link .= '&lrm;<span id="edit-slug-buttons">';
902 - $post_link .= '<button type="button" class="edit-slug button button-small hide-if-no-js" aria-label="Edit permalink">Edit</button>';
903 - $post_link .= '</span>';
904 - $post_link .= '<span id="editable-post-name-full">' . $post_slug . '</span>';
916 + } else {
917 + $post_link_message = '<span>' . __(
918 + 'Permalink is only available if the item is already assigned to a course.',
919 + 'learnpress'
920 + ) . '</span>';
921 + $post_link = sprintf( '<div id="learn-press-box-edit-slug">%s</div>', $post_link_message );
905 922 }
906 - } else {
907 - // $post_link_preview = sprintf( '<a class="button" href="%s" target="_blank">%s</a>', learn_press_get_preview_url( $post_id ), __( 'Preview', 'learnpress' ) );
908 - $post_link_message = '<span>' . __(
909 - 'Permalink only available if the item is already assigned to a course.',
910 - 'learnpress'
911 - ) . '</span>';
912 - $post_link = sprintf( '<div id="learn-press-box-edit-slug">%s</div>', $post_link_message );
923 + } elseif ( LP_COURSE_CPT === get_post_type( $post ) ) {
924 + $post_link = LP_Helper::handle_lp_permalink_structure( $post_link, $post );
913 925 }
914 926 } catch ( Throwable $e ) {
915 - if ( LP_Debug::is_debug() ) {
916 - error_log( $e->getMessage() );
917 - }
927 + error_log( $e->getMessage() );
918 928 }
919 929
920 930 return $post_link;
931 + }
932 +
933 + /**
934 + * Add "Edit with Course Builder" button below title area for courses
935 + *
936 + * @param WP_Post $post
937 + *
938 + * @since 4.3.0
939 + */
940 + public function add_course_builder_button( $post ) {
941 + if ( ! $post || LP_COURSE_CPT !== $post->post_type ) {
942 + return;
943 + }
944 +
945 + // Only show for existing courses (not new)
946 + if ( 'auto-draft' === $post->post_status ) {
947 + return;
948 + }
949 +
950 + $course_builder_url = BuilderCourseTemplate::instance()->get_link_edit( $post->ID ) ?? '';
951 + ?>
952 + <div class="lp-edit-with-course-builder" style="margin: 10px 0 20px 0;">
953 + <a href="<?php echo esc_url( $course_builder_url ); ?>" class="button button-primary button-large" style="background: #7067ED; border-color: #7067ED; display: inline-flex; align-items: center; gap: 6px; padding: 0 16px; font-size: 14px; border-radius: 3px; line-height: 3;">
954 + <svg width="26" height="18" viewBox="0 0 69 48" fill="none" xmlns="http://www.w3.org/2000/svg">
955 + <path d="M50.9291 24.84L50.2591 21.69C50.5491 21.47 50.7391 21.11 50.7391 20.71C50.7391 20.03 50.1891 19.48 49.4991 19.48C48.8091 19.48 48.2591 20.03 48.2591 20.71C48.2591 21.11 48.4491 21.46 48.7391 21.69L48.0691 24.84C47.9891 25.21 48.1791 25.56 48.4791 25.56H50.5091C50.8091 25.56 50.9991 25.21 50.9191 24.84H50.9291Z" fill="white"></path>
956 + <path d="M50.8892 13.24H50.0092V20.92H48.9892V13.21L46.2992 13.18C43.3992 8.47 38.1692 5.34 32.2192 5.34C30.8292 5.34 29.4792 5.51 28.1892 5.83L24.9492 2.53C24.7992 2.38 24.8892 2.14 25.0992 2.11L40.7292 0L48.5492 9.68L49.7592 11.17L51.0992 12.83C51.2292 12.99 51.1092 13.24 50.8992 13.23L50.8892 13.24Z" fill="white"></path>
957 + <path d="M44.7392 13.1701L43.1392 17.1401C40.7292 13.1101 36.3092 10.4101 31.2592 10.4101C29.9992 10.4101 28.7892 10.5801 27.6292 10.8901L29.2292 6.93014C30.1992 6.74014 31.1992 6.64014 32.2192 6.64014C37.4092 6.64014 41.9892 9.22014 44.7392 13.1701Z" fill="white"></path>
958 + <path d="M25.4692 23.6899V23.8499C25.4692 23.9599 25.4592 24.0699 25.4592 24.1899C25.4592 24.0199 25.4592 23.8499 25.4692 23.6899Z" fill="white"></path>
959 + <path d="M43.3692 24.2601C43.3692 25.2901 43.2392 26.2901 42.9892 27.2501C42.3892 29.5401 41.1192 31.5601 39.4092 33.1001C37.9992 34.3601 36.2892 35.2901 34.3892 35.7701C33.4492 36.0101 32.4592 36.1401 31.4392 36.1401H27.9692V35.8001C27.9692 35.6601 27.9792 35.5301 27.9992 35.3901C28.2092 33.2201 29.5592 31.3901 31.4492 30.4901C31.6092 30.4101 31.7692 30.3401 31.9292 30.2801C32.1692 30.1901 32.4192 30.1201 32.6692 30.0601C32.7292 30.0501 32.7992 30.0301 32.8592 30.0201C35.4892 29.4101 37.4492 27.0601 37.4492 24.2501C37.4492 21.2701 35.2392 18.8001 32.3592 18.3901C32.0792 18.3501 31.7892 18.3301 31.4992 18.3301C31.2392 18.3301 30.9992 18.3501 30.7492 18.3801C28.2992 18.6901 26.2592 20.4801 25.6492 22.8201C25.5292 23.2901 25.4792 23.7701 25.4792 24.2401V42.7601C25.1492 45.6001 22.8092 47.8301 19.9092 47.9901H19.5592H16.4792C18.3092 46.6501 19.5092 44.5001 19.5092 42.0701V23.7001C19.5092 23.5601 19.5192 23.4301 19.5392 23.3001C19.6292 22.2301 19.8492 21.1901 20.2092 20.2201C20.4592 19.5401 20.7692 18.8801 21.1292 18.2501C21.7592 17.1801 22.5492 16.2201 23.4692 15.4001C24.6192 14.3701 25.9792 13.5601 27.4692 13.0401C28.7092 12.6001 30.0492 12.3701 31.4392 12.3701C32.4792 12.3701 33.4792 12.5001 34.4392 12.7501C36.6892 13.3301 38.6792 14.5401 40.2092 16.1901C40.2592 16.2401 40.3092 16.3001 40.3592 16.3501C40.3592 16.3501 40.3592 16.3501 40.3692 16.3601C41.9592 18.1401 43.0192 20.4101 43.2992 22.9001C43.3293 23.1701 43.3492 23.4501 43.3692 23.7201C43.3692 23.8901 43.3692 24.0601 43.3692 24.2401V24.2601Z" fill="white"></path>
960 + <path d="M25.4692 23.6899V23.8499C25.4692 23.9599 25.4592 24.0699 25.4592 24.1899C25.4592 24.0199 25.4592 23.8499 25.4692 23.6899Z" fill="white"></path>
961 + <path d="M6.13917 42.0799H18.0692C18.0592 45.3499 15.3792 47.9999 12.0892 47.9999H6.11917C2.83917 47.9999 0.16917 45.3499 0.14917 42.0799V12.3799H0.18917C3.46917 12.3799 6.13917 15.0299 6.13917 18.2999V42.0799Z" fill="white"></path>
962 + <path d="M67.6736 23.2845L63.9566 19.5676C63.1998 18.8108 61.9757 18.8108 61.219 19.5676L59.0266 21.7599L65.4812 28.2145L67.6736 26.0222C68.4303 25.2654 68.4303 24.0413 67.6736 23.2845Z" fill="white"></path>
963 + <path d="M45.4722 45.0411L46.3513 45.9203L42.078 46.7883C42.078 46.7883 42.0557 46.3432 41.477 45.7534C40.8983 45.1747 40.442 45.1524 40.442 45.1524L41.3101 40.879L42.1892 41.7582L59.817 24.1305L58.2256 22.5391L40.5979 40.1668L39.2513 46.7883C39.1066 47.4894 39.7298 48.1126 40.4309 47.968L47.0525 46.6214L64.6802 28.9937L63.0888 27.4023L45.4611 45.03L45.4722 45.0411Z" fill="white"></path>
964 + <path d="M60.6182 24.9316L42.9905 42.5594L44.6932 44.2621L62.3209 26.6343L60.6182 24.9316Z" fill="white"></path>
965 + </svg>
966 + <?php esc_html_e( 'Edit with Course Builder', 'learnpress' ); ?>
967 + </a>
968 + </div>
969 + <?php
921 970 }
922 971
923 972 /**
924 973 * @return false|string