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 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 All 140 releases
← All changes | inc/admin/class-lp-admin.php +335 -269 4.1.7.1 → 4.4.9 View file →
@@ -1,14 +1,20 @@
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\Helpers\Template;
10 +use LearnPress\Models\CourseModel;
11 +use LearnPress\TemplateHooks\Admin\Notices\AdminNotesTemplate;
12 +use LearnPress\TemplateHooks\TemplateAJAX;
13 +use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderCourseTemplate;
14 +
15 +defined( 'ABSPATH' ) || exit;
16 +
11 17 if ( ! class_exists( 'LP_Admin' ) ) {
12 18 /**
13 19 * Class LP_Admin
14 20 */
@@ -14,32 +20,31 @@
14 20 */
15 21 class LP_Admin {
16 22 protected static $instance;
17 23
18 - /**
19 - * @var array
20 - */
21 - protected $_static_pages = false;
24 + protected $pages = [];
22 25
23 26 /**
24 27 * Constructor
25 28 */
26 29 protected function __construct() {
30 + $this->pages = [
31 + 'courses' => __( 'Courses', 'learnpress' ),
32 + 'instructors' => __( 'Instructors', 'learnpress' ),
33 + 'single_instructor' => __( 'Single Instructors', 'learnpress' ),
34 + 'profile' => __( 'Profile', 'learnpress' ),
35 + 'checkout' => __( 'Checkout', 'learnpress' ),
36 + 'become_a_teacher' => __( 'Become an Instructor', 'learnpress' ),
37 + ];
27 38 $this->includes();
28 39 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' ) );
40 + //add_action( 'delete_user_form', array( $this, 'delete_user_form' ) );
41 + add_action( 'admin_footer', array( $this, 'admin_notices' ) );
36 42 add_action( 'admin_enqueue_scripts', array( $this, 'load_modal' ) );
37 -
38 43 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 );
44 + //add_filter( 'manage_users_custom_column', array( $this, 'users_custom_column' ), 10, 3 );
45 + //add_filter( 'manage_pages_columns', array( $this, 'page_columns_head' ) );
46 + //add_filter( 'manage_pages_custom_column', array( $this, 'page_columns_content' ), 10, 2 );
42 47 add_filter( 'views_edit-page', array( $this, 'views_pages' ), 10 );
43 48 add_filter( 'views_users', array( $this, 'views_users' ), 10, 1 );
44 49 add_filter( 'user_row_actions', array( $this, 'user_row_actions' ), 10, 2 );
45 50 add_filter( 'get_pages', array( $this, 'add_empty_page' ), 1000, 2 );
@@ -49,9 +54,9 @@
49 54 LP_Request::register( 'lp-action', array( $this, 'filter_users' ) );
50 55
51 56 add_filter( 'learn-press/modal-search-items-args', array( $this, 'filter_modal_search' ) );
52 57
53 - add_filter(
58 + /*add_filter(
54 59 'learn-press/dismissed-notice-response',
55 60 array(
56 61 $this,
57 62 'on_dismissed_notice_response',
@@ -57,9 +62,9 @@
57 62 'on_dismissed_notice_response',
58 63 ),
59 64 10,
60 65 2
61 - );
66 + );*/
62 67
63 68 // get list items course of user | tungnx
64 69 add_action( 'pre_get_posts', array( $this, 'get_course_items_of_user_backend' ), 10 );
65 70 add_action( 'pre_get_posts', array( $this, 'get_pages_of_lp' ), 10 );
@@ -65,8 +70,28 @@
65 70 add_action( 'pre_get_posts', array( $this, 'get_pages_of_lp' ), 10 );
66 71
67 72 // Set link item course when edit on Backend | tungnx
68 73 add_filter( 'get_sample_permalink_html', array( $this, 'lp_course_set_link_item_backend' ), 10, 5 );
74 +
75 + // Add "Edit with Course Builder" button below title area for courses
76 + add_action( 'edit_form_after_title', array( $this, 'add_course_builder_button' ) );
77 +
78 + /*add_action(
79 + 'admin_init',
80 + function () {
81 + // From LP v4.2.3 temporary run create pages to add page instructors, single instructor for client upgrade LP.
82 + // After a long time, will remove this code.
83 + if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
84 + LP_Install::create_pages();
85 + }
86 + }
87 + );*/
88 +
89 + add_filter( 'users_list_table_query_args', [ $this, 'exclude_temp_users' ] );
90 +
91 + // Show label 'LearnPress Page' for page of LearnPress.
92 + //add_filter('post_states_html');
93 + add_filter( 'display_post_states', [ $this, 'show_label_page_type' ], 10, 2 );
69 94 }
70 95
71 96 /**
72 97 * @since 3.2.6
@@ -71,15 +96,16 @@
71 96 /**
72 97 * @since 3.2.6
73 98 */
74 99 public function load_modal() {
75 - if ( in_array( get_post_type(), array( LP_COURSE_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, LP_ORDER_CPT ) ) ) {
100 + // Now only add item(s) when create new Order is using.
101 + if ( in_array( get_post_type(), array( LP_ORDER_CPT ) ) ) {
76 102 LP_Modal_Search_Items::instance();
77 103 }
78 104
79 - if ( in_array( get_post_type(), array( LP_ORDER_CPT ) ) ) {
105 + /*if ( in_array( get_post_type(), array( LP_ORDER_CPT ) ) ) {
80 106 LP_Modal_Search_Users::instance();
81 - }
107 + }*/
82 108 }
83 109
84 110 /**
85 111 * @param $options
@@ -121,9 +147,9 @@
121 147 if ( $active_plugins ) {
122 148 if ( $search ) {
123 149 foreach ( $search as $k => $v ) {
124 150 if ( in_array( $k, $active_plugins ) ) {
125 - $count_activated ++;
151 + ++ $count_activated;
126 152 }
127 153 }
128 154 }
129 155 }
@@ -179,9 +205,9 @@
179 205 * @param int $id
180 206 *
181 207 * @return bool
182 208 */
183 - protected function _is_wc_page( $id ) {
209 + /*protected function _is_wc_page( $id ) {
184 210 if ( class_exists( 'WooCommerce' ) ) {
185 211 if ( ! class_exists( 'WC_Admin_Post_Types' ) ) {
186 212 include_once dirname( WC_PLUGIN_FILE ) . '/includes/admin/class-wc-admin-post-types.php';
187 213 }
@@ -206,11 +232,11 @@
206 232 }
207 233 }
208 234
209 235 return false;
210 - }
236 + }*/
211 237
212 - public function wc_add_display_post_states( $post_states, $post ) {
238 + /*public function wc_add_display_post_states( $post_states, $post ) {
213 239 if ( wc_get_page_id( 'shop' ) === $post->ID ) {
214 240 $post_states['wc_page_for_shop'] = __( 'Shop Page', 'learnpress' );
215 241 }
216 242
@@ -230,9 +256,9 @@
230 256 $post_states['wc_page_for_terms'] = __( 'Terms and Conditions Page', 'learnpress' );
231 257 }
232 258
233 259 return $post_states;
234 - }
260 + }*/
235 261
236 262 /**
237 263 * Check if a page is set for Paid Membership Pro.
238 264 *
@@ -239,9 +265,9 @@
239 265 * @param int $id
240 266 *
241 267 * @return bool|mixed
242 268 */
243 - protected function _is_pmpro_page( $id ) {
269 + /*protected function _is_pmpro_page( $id ) {
244 270 global $pmpro_pages;
245 271 if ( $pmpro_pages ) {
246 272 $pages = array(
247 273 'account' => __( 'Account', 'learnpress' ),
@@ -260,9 +286,9 @@
260 286 }
261 287 }
262 288
263 289 return false;
264 - }
290 + }*/
265 291
266 292 /**
267 293 * Check if a page is set for Paid Membership Pro.
268 294 *
@@ -269,9 +295,9 @@
269 295 * @param int $id
270 296 *
271 297 * @return bool|mixed
272 298 */
273 - protected function _is_bp_page( $id ) {
299 + /*protected function _is_bp_page( $id ) {
274 300 if ( function_exists( 'buddypress' ) ) {
275 301 $bp_pages = get_option( 'bp-pages' );
276 302 if ( ! $bp_pages ) {
277 303 return false;
@@ -291,56 +317,56 @@
291 317 }
292 318 }
293 319
294 320 return false;
295 - }
321 + }*/
296 322
297 323 /**
298 - * @param string $plugin
324 + * Get pages is publish set by LearnPress.
299 325 *
300 - * @return array|bool
326 + * @return array
301 327 */
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 - );
328 + protected function _get_static_pages(): array {
329 + $static_pages = [];
330 + foreach ( $this->pages as $name => $title ) {
331 + $page_id = learn_press_get_page_id( $name );
310 332
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 - );
333 + if ( $page_id && 'publish' === get_post_status( $page_id ) ) {
334 + $static_pages[ $page_id ] = $title;
335 + }
336 + }
317 337
318 - foreach ( $all_pages as $name => $title ) {
319 - $page_id = learn_press_get_page_id( $name );
338 + return $static_pages;
339 + }
320 340
321 - if ( $page_id && 'publish' === get_post_status( $page_id ) ) {
322 - $this->_static_pages['learnpress'][ $page_id ] = $title;
341 + /**
342 + * Show label LearnPress Page for pages set by LearnPress.
343 + *
344 + * @param array $post_states
345 + * @param WP_Post $post
346 + *
347 + * @return array
348 + * @since 4.3.2.6
349 + * @version 1.0.0
350 + */
351 + public function show_label_page_type( $post_states, $post ) {
352 + $post_type = get_post_type( $post );
353 + if ( $post_type !== 'page' ) {
354 + return $post_states;
355 + }
323 356
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 - }
357 + $page_id_compare = $post->ID;
358 + foreach ( $this->_get_static_pages() as $page_id => $title ) {
359 + if ( $page_id == $page_id_compare ) {
360 + $post_states['lp_page'] = sprintf(
361 + '<span class="is-lp-page">%s</span>',
362 + 'LearnPress ' . $title . ' Page'
363 + );
364 + break;
339 365 }
340 366 }
341 367
342 - return $plugin ? ( ! empty( $this->_static_pages[ $plugin ] ) ? $this->_static_pages[ $plugin ] : false ) : $this->_static_pages;
368 + return $post_states;
343 369 }
344 370
345 371 /**
346 372 * Add new column to WP Pages manage to show what page is assigned to.
@@ -348,9 +374,9 @@
348 374 * @param array $columns
349 375 *
350 376 * @return array
351 377 */
352 - public function page_columns_head( $columns ) {
378 + /*public function page_columns_head( $columns ) {
353 379
354 380 $_columns = $columns;
355 381 $columns = array();
356 382
@@ -361,17 +387,17 @@
361 387 $columns[ $name ] = $text;
362 388 }
363 389
364 390 return $columns;
365 - }
391 + }*/
366 392
367 393 /**
368 394 * Display the page is assigned to LP Page.
369 395 *
370 396 * @param string $column_name
371 - * @param int $post
397 + * @param int $post
372 398 */
373 - public function page_columns_content( $column_name, $post ) {
399 + /*public function page_columns_content( $column_name, $post ) {
374 400 $pages = $this->_get_static_pages();
375 401 switch ( $column_name ) {
376 402 case 'lp-page':
377 403 if ( ! empty( $pages['learnpress'][ $post ] ) ) {
@@ -391,9 +417,9 @@
391 417 );
392 418 }
393 419 }
394 420 }
395 - }
421 + }*/
396 422
397 423 /**
398 424 * @param $actions
399 425 *
@@ -399,15 +425,13 @@
399 425 *
400 426 * @return mixed
401 427 */
402 428 public function views_pages( $actions ) {
403 - $this->_get_static_pages();
429 + $pages = $this->_get_static_pages();
404 430
405 - $pages = $this->_get_static_pages( 'learnpress' );
406 -
407 431 if ( $pages ) {
408 432 $text = sprintf( __( 'LearnPress Pages (%d)', 'learnpress' ), sizeof( $pages ) );
409 - if ( 'yes' !== LP_Request::get( 'lp-page' ) ) {
433 + if ( 'yes' !== LP_Request::get_param( 'lp-page' ) ) {
410 434 $actions['lp-page'] = sprintf(
411 435 '<a href="%s">%s</a>',
412 436 admin_url( 'edit.php?post_type=page&lp-page=yes' ),
413 437 $text
@@ -427,11 +451,15 @@
427 451 *
428 452 * @return mixed
429 453 */
430 454 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' );
455 + if ( ! is_admin() || ! $q->is_main_query() ) {
456 + return $q;
457 + }
433 458
459 + if ( 'page' == LP_Request::get_param( 'post_type' ) && 'yes' == LP_Request::get_param( 'lp-page' ) ) {
460 + $ids = $this->_get_static_pages();
461 +
434 462 if ( ! empty( $ids ) ) {
435 463 $ids = array_keys( $ids );
436 464 $q->set( 'post__in', $ids );
437 465 }
@@ -442,24 +470,27 @@
442 470
443 471 /**
444 472 * Add actions to users list
445 473 *
446 - * @param array $actions
474 + * @param array $actions
447 475 * @param WP_User $user
448 476 *
449 477 * @return mixed
450 478 */
451 479 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 ) {
480 + $pending_request = self::get_pending_requests();
481 + if ( LP_Request::get_param( 'lp-action' ) == 'pending-request' && $pending_request ) {
454 482 $actions = array();
483 + $nonce = 'nonce=' . wp_create_nonce( 'lp-action-permit-role-teacher' );
455 484 if ( in_array( $user->ID, $pending_request ) ) {
456 485 $actions['accept'] = sprintf(
457 - '<a href="' . admin_url( 'users.php?lp-action=accept-request&user_id=' . $user->ID ) . '">%s</a>',
486 + '<a href="%s">%s</a>',
487 + admin_url( "users.php?lp-action=accept-request&user_id={$user->ID}&{$nonce}" ),
458 488 _x( 'Accept', 'pending-request', 'learnpress' )
459 489 );
460 490 $actions['delete deny'] = sprintf(
461 - '<a class="submitdelete" href="' . admin_url( 'users.php?lp-action=deny-request&user_id=' . $user->ID ) . '">%s</a>',
491 + '<a class="submitdelete" href="%s">%s</a>',
492 + admin_url( "users.php?lp-action=deny-request&user_id={$user->ID}&{$nonce}" ),
462 493 _x( 'Deny', 'pending-request', 'learnpress' )
463 494 );
464 495 }
465 496 }
@@ -466,9 +497,38 @@
466 497
467 498 return $actions;
468 499 }
469 500
501 + public function exclude_temp_users( $args ) {
502 + if ( LP_Request::get_param( 'lp-action' ) == 'pending-request' ) {
503 + $args['include'] = self::get_pending_requests();
504 + }
505 +
506 + return $args;
507 + }
508 +
470 509 /**
510 + * Get pending requests be come a Teacher.
511 + *
512 + * @return array
513 + */
514 + public static function get_pending_requests() {
515 + global $wpdb;
516 + $query = $wpdb->prepare(
517 + "
518 + SELECT ID
519 + FROM {$wpdb->users} u
520 + INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s
521 + WHERE um.meta_value = %s
522 + ",
523 + '_requested_become_teacher',
524 + 'yes'
525 + );
526 +
527 + return $wpdb->get_col( $query );
528 + }
529 +
530 + /**
471 531 * Filter user by custom param
472 532 *
473 533 * @param string $action
474 534 */
@@ -476,38 +536,59 @@
476 536 if ( ! current_user_can( 'administrator' ) ) {
477 537 return;
478 538 }
479 539
480 - $user_id = LP_Request::get_int( 'user_id' );
540 + $user_id = LP_Request::get_param( 'user_id', 'int' );
541 + if ( ! $user_id || ! get_user_by( 'id', $user_id ) ) {
542 + return;
543 + }
481 544
482 - if ( ! $user_id || ! get_user_by( 'id', $user_id ) ) {
545 + $nonce = LP_Request::get_param( 'nonce' );
546 + if ( ! wp_verify_nonce( $nonce, 'lp-action-permit-role-teacher' ) ) {
483 547 return;
484 548 }
485 549
486 550 $user_data = get_userdata( $user_id );
551 + if ( in_array( $action, array( 'accept-request', 'deny-request' ) ) ) {
552 + delete_user_meta( $user_id, '_requested_become_teacher' );
553 + }
487 554
488 - if ( in_array( $action, array( 'accept-request', 'deny-request' ) ) ) {
555 + switch ( $action ) {
556 + case 'accept-request':
557 + $be_teacher = new WP_User( $user_id );
558 + $be_teacher->set_role( LP_TEACHER_ROLE );
489 559
490 - delete_user_meta( $user_id, '_requested_become_teacher' );
560 + /**
561 + * Send email to user when admin accept user become a teacher
562 + * @use SendEmailAjax::send_mail_become_a_teacher_accept
563 + */
564 + $data_send = [
565 + 'params' => [ $user_data->user_email ],
566 + 'lp-load-ajax' => 'send_mail_become_a_teacher_accept',
567 + ];
568 + LPBackgroundAjax::handle( $data_send );
491 569
492 - switch ( $action ) {
493 - case 'accept-request':
494 - $be_teacher = new WP_User( $user_id );
495 - $be_teacher->set_role( LP_TEACHER_ROLE );
570 + do_action( 'learn-press/user-become-a-teacher-accept', $user_data->user_email );
571 + wp_redirect( admin_url( 'users.php?lp-action=accepted-request&user_id=' . $user_id ) );
572 + exit();
573 + case 'deny-request':
574 + /**
575 + * Send email to user when admin accept user become a teacher
576 + * @use SendEmailAjax::send_mail_become_a_teacher_deny
577 + */
578 + $data_send = [
579 + 'params' => [ $user_data->user_email ],
580 + 'lp-load-ajax' => 'send_mail_become_a_teacher_deny',
581 + ];
582 + LPBackgroundAjax::handle( $data_send );
496 583
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 - }
584 + do_action( 'learn-press/user-become-a-teacher-deny', $user_data->user_email );
585 + wp_redirect( admin_url( 'users.php?lp-action=denied-request&user_id=' . $user_id ) );
586 + exit();
505 587 }
506 588 }
507 589
508 590 public function users_custom_column( $content, $column_name, $user_id ) {
509 -
510 591 }
511 592
512 593 /**
513 594 * Add new view to users views for filtering user by "pending request" of "become a teacher".
@@ -516,12 +597,12 @@
516 597 *
517 598 * @return mixed
518 599 */
519 600 public function views_users( $views ) {
520 - $pending_request = LP_User_Factory::get_pending_requests();
601 + $pending_request = self::get_pending_requests();
521 602
522 603 if ( $pending_request ) {
523 - if ( LP_Request::get_string( 'lp-action' ) == 'pending-request' ) {
604 + if ( LP_Request::get_param( 'lp-action' ) == 'pending-request' ) {
524 605 $class = ' class="current"';
525 606 foreach ( $views as $k => $view ) {
526 607 $views[ $k ] = preg_replace( '!class="current"!', '', $view );
527 608 }
@@ -540,62 +621,8 @@
540 621 return $views;
541 622 }
542 623
543 624 /**
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 625 * Custom admin body classes.
599 626 *
600 627 * @param array $classes
601 628 *
@@ -619,54 +646,64 @@
619 646
620 647 return $classes;
621 648 }
622 649
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>
650 + /**
651 + * Display notices on Backend.
652 + */
653 + public function admin_notices() {
654 + if ( function_exists( 'get_current_screen' ) ) {
655 + $wp_screen = get_current_screen();
656 + // Not run on course edit screen, it slows, can affect performance edit course.
657 + if ( $wp_screen->id === LP_COURSE_CPT ) {
658 + return;
659 + }
660 + }
661 +
662 + // Request accept/denied user can become a teacher.
663 + $action_become_teacher = LP_Request::get_param( 'lp-action' );
664 + $user_id = LP_Request::get_param( 'user_id', 0, 'int' );
665 + $type_action_become_teacher = array( 'accepted-request', 'denied-request' );
666 + if ( in_array( $action_become_teacher, $type_action_become_teacher ) && $user_id && get_user_by( 'id', $user_id ) ) {
667 + ?>
668 + <div class="updated notice">
669 + <p>
629 670 <?php
630 671 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 - )
672 + __( 'A user has %s to become a teacher.', 'learnpress' ),
673 + $action_become_teacher == 'accepted-request' ? 'accepted' : 'denied'
674 + );
634 675 ?>
635 - </p>
636 - </div>
637 - <?php
638 - }
676 + </p>
677 + </div>
678 + <?php
639 679 }
640 - }
641 680
642 - /**
643 - * Notices outdated templates.
644 - */
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'] ?? '' );
681 + // Load Ajax notes here
682 + /** @use AdminNotesTemplate::render_notices */
683 + $html_notices = TemplateAJAX::load_content_via_ajax(
684 + [
685 + 'method_request' => 'GET',
686 + 'id_url' => 'admin-notices',
687 + 'html_loading_before_show_content' => '',
688 + ],
689 + [
690 + 'class' => AdminNotesTemplate::class,
691 + 'method' => 'render_notices',
692 + ]
693 + );
649 694
650 - if ( $page == 'learn-press-tools' && $tab == 'templates' ) {
651 - return;
652 - }
695 + wp_enqueue_script( 'lp-admin-notices' );
653 696
654 - if ( LP_Outdated_Template_Helper::detect_outdated_template() ) {
655 - learn_press_admin_view( 'html-admin-notice-templates' );
656 - }
657 - }
697 + echo Template::instance()->nest_elements(
698 + [
699 + '<div class="learn-press-admin-notices notice">' => '</div>',
700 + ],
701 + $html_notices
702 + );
658 703 }
659 704
660 705 /**
661 - * Update option data user rated.
662 - */
663 - public function rated() {
664 - update_option( 'learn_press_message_user_rated', 'yes' );
665 - die();
666 - }
667 -
668 - /**
669 706 * Admin footer add review.
670 707 *
671 708 * @param $footer_text
672 709 *
@@ -682,9 +719,9 @@
682 719 ) ) {
683 720 if ( ! get_option( 'learn_press_message_user_rated' ) ) {
684 721 $footer_text = sprintf(
685 722 __(
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.',
723 + '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 724 'learnpress'
688 725 ),
689 726 '<a href="https://wordpress.org/support/plugin/learnpress/reviews/?filter=5#postform" target="_blank" class="lp-rating-link" data-rated="' . esc_attr__(
690 727 'Thanks :)',
@@ -691,30 +728,8 @@
691 728 'learnpress'
692 729 ) . '">',
693 730 '</a>'
694 731 );
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 732 }
718 733 }
719 734
720 735 return $footer_text;
@@ -719,11 +734,11 @@
719 734
720 735 return $footer_text;
721 736 }
722 737
723 - function delete_user_form() {
738 + /*function delete_user_form() {
724 739 // What should be displayed here?
725 - }
740 + }*/
726 741
727 742 /**
728 743 * Delete records related user being deleted in other tables
729 744 *
@@ -735,15 +750,16 @@
735 750
736 751 /**
737 752 * Send data to join newsletter or dismiss.
738 753 *
739 - * @param array $data
754 + * @param array $data
740 755 * @param string $notice
741 756 *
742 757 * @return array
743 758 * @since 3.0.10
759 + * @deprecated 4.2.3.1
744 760 */
745 - public function on_dismissed_notice_response( $data, $notice ) {
761 + /*public function on_dismissed_notice_response( $data, $notice ) {
746 762 switch ( $notice ) {
747 763 case 'skip-setup-wizard':
748 764 delete_option( 'learn_press_install' );
749 765 break;
@@ -754,9 +770,9 @@
754 770 }
755 771
756 772 $user = learn_press_get_current_user();
757 773 if ( ! $user || $user->get_email() == '' ) {
758 - $data['error'] = __( 'Fail while joining newsletter! Please try again!', 'learnpress' );
774 + $data['error'] = __( 'Failed while joining the newsletter! Please try again!', 'learnpress' );
759 775 }
760 776
761 777 $url = 'https://thimpress.com/mailster/subscribe';
762 778 $response = wp_remote_post(
@@ -783,9 +799,9 @@
783 799 $error_message = $response->get_error_message();
784 800 $data['message'] = __( 'Something went wrong: ', 'learnpress' ) . $error_message;
785 801 } else {
786 802 $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.',
803 + 'Thank you for subscribing! Please check and click the confirmation link from the email that we\'ve just sent to your inbox.',
788 804 'learnpress'
789 805 );
790 806 }
791 807 }
@@ -790,9 +806,9 @@
790 806 }
791 807 }
792 808
793 809 return $data;
794 - }
810 + }*/
795 811
796 812 /**
797 813 * Include all classes and functions used for admin
798 814 */
@@ -799,10 +815,18 @@
799 815 public function includes() {
800 816 // Common function used in admin
801 817 include_once 'lp-admin-functions.php';
802 818 include_once 'lp-admin-actions.php';
803 - require_once LP_PLUGIN_PATH . 'inc/background-process/class-lp-background-query-items.php';
804 819 include_once 'class-lp-admin-assets.php';
820 + LP_Admin_Assets::instance();
821 + // For MCP
822 + if ( learn_press_is_mcp_available() ) {
823 + include_once 'class-lp-admin-mcp-api-keys.php';
824 + LP_Admin_MCP_API_Keys::instance();
825 + }
826 + // End MCP
827 + include_once 'class-lp-admin-webhooks.php';
828 + LP_Admin_Webhooks::instance();
805 829 include_once 'class-lp-admin-dashboard.php';
806 830 // include_once 'class-lp-admin-tools.php';
807 831 include_once 'class-lp-admin-ajax.php';
808 832 include_once 'editor/class-lp-admin-editor.php';
@@ -807,19 +831,19 @@
807 831 include_once 'class-lp-admin-ajax.php';
808 832 include_once 'editor/class-lp-admin-editor.php';
809 833 include_once 'class-lp-admin-menu.php';
810 834 include_once 'helpers/class-lp-outdated-template-helper.php';
811 - include_once 'helpers/class-lp-plugins-helper.php';
812 835 include_once 'class-lp-modal-search-items.php';
813 - include_once 'class-lp-modal-search-users.php';
836 + //include_once 'class-lp-modal-search-users.php';
814 837 include_once 'class-lp-setup-wizard.php';
815 838 // include_once 'class-lp-updater.php';
816 - include_once 'class-lp-install-sample-data.php';
817 - include_once 'class-lp-reset-data.php';
839 + // include_once 'class-lp-install-sample-data.php'; // Replaced by LearnPress\Ajax\SampleDataAJAX.
840 + // include_once 'class-lp-reset-data.php'; // Deprecated: replaced by CourseToolsAjax::reset_progress_items_course.
818 841 include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/course/settings.php';
842 + include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/course/class-lp-meta-box-course-offline.php';
819 843 include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/quiz/settings.php';
820 844 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';
845 + //include_once LP_PLUGIN_PATH . 'inc/admin/views/meta-boxes/question/settings.php';
822 846 }
823 847
824 848 /**
825 849 * Get courses, item's courses on Backend page post_type
@@ -830,9 +854,9 @@
830 854 if ( ! $query->is_main_query() ) {
831 855 return;
832 856 }
833 857
834 - global $post_type, $pagenow;
858 + /*global $post_type, $pagenow;
835 859
836 860 if ( current_user_can( ADMIN_ROLE ) ) {
837 861 return;
838 862 }
@@ -847,25 +871,26 @@
847 871 );
848 872
849 873 if ( ! in_array( $post_type, $post_type_valid ) ) {
850 874 return;
851 - }
875 + }*/
852 876
853 877 // $query->set( 'author', get_current_user_id() );
854 878
855 - $query = apply_filters( 'learnpress/get-post-type-lp-on-backend', $query );
879 + // Hook only Co-instructor using.
880 + return apply_filters( 'learnpress/get-post-type-lp-on-backend', $query );
856 881
857 882 //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 );
883 + //remove_filter( 'pre_get_posts', array( $this, 'get_course_items_of_user_backend' ), 10 );
859 884 }
860 885
861 886 /**
862 887 * Set link item of course when edit item on Backend
863 888 *
864 - * @param string $post_link
865 - * @param int $post_id
866 - * @param string $new_title
867 - * @param string $new_slug
889 + * @param string $post_link
890 + * @param int $post_id
891 + * @param string $new_title
892 + * @param string $new_slug
868 893 * @param WP_Post|null $post
869 894 *
870 895 * @return string
871 896 * @author tungnx
@@ -872,45 +897,47 @@
872 897 * @since 3.2.7.5
873 898 * @version 4.0.1
874 899 */
875 900 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 901 try {
881 - $course_id_of_item = LP_Course_DB::getInstance()->get_course_by_item_id( $post->ID );
902 + if ( in_array( $post->post_type, CourseModel::item_types_support() ) ) {
903 + $course_id_of_item = LP_Course_DB::getInstance()->get_course_by_item_id( $post->ID );
904 + if ( $course_id_of_item ) {
905 + $course = learn_press_get_course( $course_id_of_item );
906 + if ( $course ) {
907 + $link_item = urldecode( $course->get_item_link( $post->ID ) );
908 + $post_slug = $post->post_name;
909 + $link_item_edit_slug = preg_replace( '/' . $post_slug . '$/', '', $link_item );
882 910
883 - if ( $course_id_of_item ) {
884 - $course = learn_press_get_course( $course_id_of_item );
911 + // For update new slug
912 + if ( $new_slug ) {
913 + $post_slug = $new_slug;
914 + }
915 + $post_slug = urldecode( $post_slug );
885 916
886 - if ( $course ) {
887 - $link_item = $course->get_item_link( $post->ID );
917 + $slug_arr = explode( '/', $link_item_edit_slug );
918 + $count_slug = count( $slug_arr );
919 + unset( $slug_arr[ $count_slug - 2 ] );
920 + $link_item_edit_slug = implode( '/', $slug_arr );
888 921
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;
922 + $post_link = '<strong>Permalink: </strong>';
923 + $post_link .= '<span id="sample-permalink">';
924 + $post_link .= '<a href="' . $link_item . '">' . $link_item_edit_slug . '<span id="editable-post-name">' . $post_slug . '</span>/</a>';
925 + $post_link .= '</span>';
926 + $post_link .= '&lrm;<span id="edit-slug-buttons">';
927 + $post_link .= '<button type="button" class="edit-slug button button-small hide-if-no-js" aria-label="Edit permalink">Edit</button>';
928 + $post_link .= '</span>';
929 + $post_link .= '<span id="editable-post-name-full">' . $post_slug . '</span>';
895 930 }
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>';
931 + } else {
932 + $post_link_message = '<span>' . __(
933 + 'Permalink is only available if the item is already assigned to a course.',
934 + 'learnpress'
935 + ) . '</span>';
936 + $post_link = sprintf( '<div id="learn-press-box-edit-slug">%s</div>', $post_link_message );
905 937 }
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 );
938 + } elseif ( LP_COURSE_CPT === get_post_type( $post ) ) {
939 + $post_link = LP_Helper::handle_lp_permalink_structure( $post_link, $post );
913 940 }
914 941 } catch ( Throwable $e ) {
915 942 error_log( $e->getMessage() );
916 943 }
@@ -915,8 +942,47 @@
915 942 error_log( $e->getMessage() );
916 943 }
917 944
918 945 return $post_link;
946 + }
947 +
948 + /**
949 + * Add "Edit with Course Builder" button below title area for courses
950 + *
951 + * @param WP_Post $post
952 + *
953 + * @since 4.3.0
954 + */
955 + public function add_course_builder_button( $post ) {
956 + if ( ! $post || LP_COURSE_CPT !== $post->post_type ) {
957 + return;
958 + }
959 +
960 + // Only show for existing courses (not new)
961 + if ( 'auto-draft' === $post->post_status ) {
962 + return;
963 + }
964 +
965 + $course_builder_url = BuilderCourseTemplate::instance()->get_link_edit( $post->ID ) ?? '';
966 + ?>
967 + <div class="lp-edit-with-course-builder" style="margin: 10px 0 20px 0;">
968 + <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;">
969 + <svg width="26" height="18" viewBox="0 0 69 48" fill="none" xmlns="http://www.w3.org/2000/svg">
970 + <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>
971 + <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>
972 + <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>
973 + <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>
974 + <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>
975 + <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>
976 + <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>
977 + <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>
978 + <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>
979 + <path d="M60.6182 24.9316L42.9905 42.5594L44.6932 44.2621L62.3209 26.6343L60.6182 24.9316Z" fill="white"></path>
980 + </svg>
981 + <?php esc_html_e( 'Edit with Course Builder', 'learnpress' ); ?>
982 + </a>
983 + </div>
984 + <?php
919 985 }
920 986
921 987 /**
922 988 * @return false|string