| @@ -3,9 +3,9 @@ | ||
| 3 | 3 | * Plugin Name: LearnPress |
| 4 | 4 | * Plugin URI: https://thimpress.com/learnpress |
| 5 | 5 | * Description: LearnPress is a WordPress complete solution for creating a Learning Management System (LMS). It can help you to create courses, lessons and quizzes. |
| 6 | 6 | * Author: ThimPress |
| 7 | - * Version: 4.3.7 | |
| 7 | + * Version: 4.4.9 | |
| 8 | 8 | * Author URI: http://thimpress.com |
| 9 | 9 | * Requires at least: 6.0 |
| 10 | 10 | * Requires PHP: 7.4 |
| 11 | 11 | * Text Domain: learnpress |
| @@ -18,16 +18,23 @@ | ||
| 18 | 18 | use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderCourseTemplate; |
| 19 | 19 | use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderEditCourseTemplate; |
| 20 | 20 | use LearnPress\Ajax\AI\OpenAiAjax; |
| 21 | 21 | use LearnPress\Ajax\BuilderDashboardAjax; |
| 22 | +use LearnPress\Ajax\CourseToolsAjax; | |
| 22 | 23 | use LearnPress\Ajax\CourseBuilder\CourseBuilderAjax; |
| 23 | 24 | use LearnPress\Ajax\EditCurriculumAjax; |
| 25 | +use LearnPress\Ajax\AddonsAjax; | |
| 26 | +use LearnPress\Services\AddonService; | |
| 24 | 27 | use LearnPress\Ajax\EditQuestionAjax; |
| 25 | 28 | use LearnPress\Ajax\EditQuizAjax; |
| 26 | -use LearnPress\Ajax\ExportOrderCSVAjax; | |
| 29 | +use LearnPress\Ajax\Order\ExportOrderCSVAjax; | |
| 27 | 30 | use LearnPress\Ajax\LessonAjax; |
| 28 | 31 | use LearnPress\Ajax\LoadContentViaAjax; |
| 32 | +use LearnPress\Ajax\SampleDataAJAX; | |
| 33 | +use LearnPress\Ajax\SetupWizardAjax; | |
| 34 | +use LearnPress\Ajax\AI\AIAssistantAjax; | |
| 29 | 35 | use LearnPress\Ajax\MCP\McpApiKeysAjax; |
| 36 | +use LearnPress\Ajax\Webhook\WebhooksAjax; | |
| 30 | 37 | use LearnPress\Ajax\CourseBuilder\CBEditCourseAjax; |
| 31 | 38 | use LearnPress\Ajax\SendEmailAjax; |
| 32 | 39 | use LearnPress\Background\LPBackgroundTrigger; |
| 33 | 40 | use LearnPress\ExternalPlugin\Elementor\LPElementor; |
| @@ -33,8 +40,9 @@ | ||
| 33 | 40 | use LearnPress\ExternalPlugin\Elementor\LPElementor; |
| 34 | 41 | use LearnPress\ExternalPlugin\RankMath\LPRankMath; |
| 35 | 42 | use LearnPress\ExternalPlugin\YoastSeo\LPYoastSeo; |
| 36 | 43 | use LearnPress\Gutenberg\GutenbergHandleMain; |
| 44 | +use LearnPress\Ajax\Order\RefundOrderAjax; | |
| 37 | 45 | use LearnPress\MCP\Abilities; |
| 38 | 46 | use LearnPress\MCP\Auth\ApiKeyAuthenticator; |
| 39 | 47 | use LearnPress\Models\CourseModel; |
| 40 | 48 | use LearnPress\Models\UserModel; |
| @@ -43,11 +51,16 @@ | ||
| 43 | 51 | use LearnPress\Shortcodes\CourseMaterialShortcode; |
| 44 | 52 | use LearnPress\Shortcodes\Courses\ListCoursesShortcode; |
| 45 | 53 | use LearnPress\Shortcodes\ListInstructorsShortcode; |
| 46 | 54 | use LearnPress\Shortcodes\SingleInstructorShortcode; |
| 55 | +use LearnPress\TemplateHooks\Admin\AdminAddonsPage; | |
| 47 | 56 | use LearnPress\TemplateHooks\Admin\AdminEditQizTemplate; |
| 48 | 57 | use LearnPress\TemplateHooks\Admin\AdminEditQuestionTemplate; |
| 49 | 58 | use LearnPress\TemplateHooks\Admin\AdminListStudentsEnrolled; |
| 59 | +use LearnPress\TemplateHooks\Admin\AdminStatisticsReportTable; | |
| 60 | +use LearnPress\TemplateHooks\Admin\Notices\AdminNotesTemplate; | |
| 61 | +use LearnPress\TemplateHooks\Admin\Tools\AdminCourseTools; | |
| 62 | +use LearnPress\Statistics\FilterOptionsProvider; | |
| 50 | 63 | use LearnPress\TemplateHooks\Admin\AI\AdminCreateCourseAITemplate; |
| 51 | 64 | use LearnPress\TemplateHooks\Admin\AI\AdminEditCourseCurriculumWithAITemplate; |
| 52 | 65 | use LearnPress\TemplateHooks\Admin\AI\AdminEditWithAITemplate; |
| 53 | 66 | use LearnPress\TemplateHooks\Course\AdminEditCurriculumTemplate; |
| @@ -84,11 +97,13 @@ | ||
| 84 | 97 | use LearnPress\TemplateHooks\Profile\ProfileOrderTemplate; |
| 85 | 98 | use LearnPress\TemplateHooks\Profile\ProfileQuizzesTemplate; |
| 86 | 99 | use LearnPress\TemplateHooks\Profile\ProfileStudentEnrolledTemplate; |
| 87 | 100 | use LearnPress\TemplateHooks\Profile\ProfileStudentStatisticsTemplate; |
| 101 | +use LearnPress\TemplateHooks\Course\CourseAIAssistantTemplate; | |
| 88 | 102 | use LearnPress\Widgets\LPRegisterWidget; |
| 89 | 103 | use LearnPress\WPGDPR\ErasePersonalData; |
| 90 | 104 | use LearnPress\WPGDPR\ExportPersonalData; |
| 105 | +use LearnPress\Webhook\WebhookDispatcher; | |
| 91 | 106 | |
| 92 | 107 | defined( 'ABSPATH' ) || exit(); |
| 93 | 108 | |
| 94 | 109 | if ( ! class_exists( 'LearnPress' ) ) { |
| @@ -170,8 +185,15 @@ | ||
| 170 | 185 | public static $doc_link = 'https://learnpresslms.com/docs/'; |
| 171 | 186 | |
| 172 | 187 | /** |
| 173 | 188 | * LearnPress constructor. |
| 189 | + * | |
| 190 | + * Runs on every WordPress bootstrap. Order of operations: | |
| 191 | + * 1. prepare_before_handle() - define constants, autoload, include global files and create the LP_Install instance. | |
| 192 | + * 2. Register activation/deactivation hooks unconditionally so on_activate() fires when the plugin is activated. | |
| 193 | + * 3. Stop here if tables are not installed yet; the activation hook will create them. | |
| 194 | + * 4. On normal requests with tables installed, register the init hook to load CPTs, APIs, settings and integrations. | |
| 195 | + * 5. Register remaining plugin hooks. | |
| 174 | 196 | */ |
| 175 | 197 | private function __construct() { |
| 176 | 198 | /*if ( isset( $_POST['action'] ) && 'heartbeat' === $_POST['action'] ) { |
| 177 | 199 | return; |
| @@ -179,19 +201,22 @@ | ||
| 179 | 201 | |
| 180 | 202 | try { |
| 181 | 203 | $this->prepare_before_handle(); |
| 182 | 204 | |
| 205 | + register_activation_hook( LP_PLUGIN_FILE, array( $this, 'on_activate' ) ); | |
| 206 | + register_deactivation_hook( LP_PLUGIN_FILE, array( $this, 'on_deactivate' ) ); | |
| 207 | + | |
| 183 | 208 | if ( ! LP_Install::instance()->tables_install_done() ) { |
| 184 | 209 | return; |
| 185 | 210 | } |
| 186 | 211 | |
| 187 | - // Must handle in hook init of WordPress, when loaded plugins, theme, user. | |
| 212 | + // init runs after WordPress core, plugins, theme and user are loaded. | |
| 188 | 213 | add_action( 'init', [ $this, 'lp_main_handle' ], - 1000 ); |
| 189 | 214 | |
| 190 | - // hooks . | |
| 215 | + // Register remaining plugin hooks. | |
| 191 | 216 | $this->hooks(); |
| 192 | 217 | } catch ( Throwable $e ) { |
| 193 | - error_log( __METHOD__ . ': ' . $e->getMessage() ); | |
| 218 | + LP_Debug::error_log( $e ); | |
| 194 | 219 | } |
| 195 | 220 | } |
| 196 | 221 | |
| 197 | 222 | /** |
| @@ -387,9 +412,12 @@ | ||
| 387 | 412 | AdminEditCurriculumTemplate::instance(); |
| 388 | 413 | AdminEditSettingTemplate::instance(); |
| 389 | 414 | AdminEditQizTemplate::instance(); |
| 390 | 415 | AdminEditQuestionTemplate::instance(); |
| 416 | + AdminNotesTemplate::instance(); | |
| 417 | + AdminCourseTools::instance(); | |
| 391 | 418 | CourseMaterialTemplate::instance(); |
| 419 | + CourseAIAssistantTemplate::instance(); | |
| 392 | 420 | AdminOrderItemsTemplate::instance(); |
| 393 | 421 | AdminOrderListTemplate::instance(); |
| 394 | 422 | AdminCreateCourseAITemplate::instance(); |
| 395 | 423 | AdminEditWithAITemplate::instance(); |
| @@ -394,8 +422,11 @@ | ||
| 394 | 422 | AdminCreateCourseAITemplate::instance(); |
| 395 | 423 | AdminEditWithAITemplate::instance(); |
| 396 | 424 | AdminEditCourseCurriculumWithAITemplate::instance(); |
| 397 | 425 | AdminListStudentsEnrolled::instance(); |
| 426 | + AdminStatisticsReportTable::instance(); | |
| 427 | + FilterOptionsProvider::register_flush_hooks(); | |
| 428 | + AdminAddonsPage::instance(); | |
| 398 | 429 | // WP GDPR |
| 399 | 430 | ErasePersonalData::instance(); |
| 400 | 431 | ExportPersonalData::instance(); |
| 401 | 432 | |
| @@ -476,10 +507,8 @@ | ||
| 476 | 507 | |
| 477 | 508 | include_once 'inc/lp-webhooks.php'; // Addon learnpress-2checkout-payment v4.0.1 is using, when update v4.0.2 don't need load it. |
| 478 | 509 | include_once 'inc/class-lp-request-handler.php'; |
| 479 | 510 | |
| 480 | - include_once 'inc/admin/helpers/class-lp-plugins-helper.php'; | |
| 481 | - | |
| 482 | 511 | // Todo: tungnx check those files. |
| 483 | 512 | include_once 'inc/abstracts/abstract-object-query.php'; |
| 484 | 513 | include_once 'inc/class-lp-course-query.php'; |
| 485 | 514 | include_once 'inc/abstracts/abstract-addon.php'; |
| @@ -499,8 +528,9 @@ | ||
| 499 | 528 | include_once 'inc/order/class-lp-order.php'; |
| 500 | 529 | |
| 501 | 530 | include_once 'inc/user/lp-user-functions.php'; |
| 502 | 531 | include_once 'inc/user/class-lp-user-factory.php'; |
| 532 | + WebhookDispatcher::instance(); | |
| 503 | 533 | include_once 'inc/user/abstract-lp-user.php'; |
| 504 | 534 | include_once 'inc/user/class-lp-user.php'; |
| 505 | 535 | include_once 'inc/user/class-lp-profile.php'; |
| 506 | 536 | include_once 'inc/user-item/class-lp-user-item.php'; |
| @@ -565,10 +595,8 @@ | ||
| 565 | 595 | } |
| 566 | 596 | |
| 567 | 597 | include_once 'inc/admin/class-lp-admin-ajax.php'; |
| 568 | 598 | |
| 569 | - include_once 'inc/admin/class-lp-admin-notice.php'; | |
| 570 | - | |
| 571 | 599 | // File handle install LP |
| 572 | 600 | include_once 'inc/class-lp-install.php'; |
| 573 | 601 | |
| 574 | 602 | // Meta box helper |
| @@ -715,9 +743,9 @@ | ||
| 715 | 743 | ); |
| 716 | 744 | |
| 717 | 745 | $lp_addon_version = $lp_addon_info['Version']; |
| 718 | 746 | |
| 719 | - $addon = new Lp_Addon(); | |
| 747 | + $addon = new LP_Addon(); | |
| 720 | 748 | $addon->version = $lp_addon_version; |
| 721 | 749 | $addon->plugin_base = $lp_addon; |
| 722 | 750 | $addon->require_version = $lp_addon_info['Require_LP_Version']; |
| 723 | 751 | $addon_valid = $addon->check_require_version_addon(); |
| @@ -746,17 +774,24 @@ | ||
| 746 | 774 | 'init', |
| 747 | 775 | function () { |
| 748 | 776 | LoadContentViaAjax::catch_lp_ajax(); |
| 749 | 777 | LessonAjax::catch_lp_ajax(); |
| 778 | + SampleDataAJAX::catch_lp_ajax(); | |
| 779 | + SetupWizardAjax::catch_lp_ajax(); | |
| 780 | + AddonsAjax::catch_lp_ajax(); | |
| 750 | 781 | EditCurriculumAjax::catch_lp_ajax(); |
| 751 | 782 | EditQuizAjax::catch_lp_ajax(); |
| 752 | 783 | EditQuestionAjax::catch_lp_ajax(); |
| 753 | 784 | SendEmailAjax::catch_lp_ajax(); |
| 785 | + RefundOrderAjax::catch_lp_ajax(); | |
| 754 | 786 | CourseBuilderAjax::catch_lp_ajax(); |
| 755 | 787 | OpenAiAjax::catch_lp_ajax(); |
| 788 | + AIAssistantAjax::catch_lp_ajax(); | |
| 756 | 789 | ExportOrderCSVAjax::catch_lp_ajax(); |
| 757 | 790 | McpApiKeysAjax::catch_lp_ajax(); |
| 791 | + WebhooksAjax::catch_lp_ajax(); | |
| 758 | 792 | CBEditCourseAjax::catch_lp_ajax(); |
| 793 | + CourseToolsAjax::catch_lp_ajax(); | |
| 759 | 794 | |
| 760 | 795 | do_action( 'learn-press/register-ajax-handlers' ); |
| 761 | 796 | }, |
| 762 | 797 | 11 |
| @@ -764,12 +799,9 @@ | ||
| 764 | 799 | |
| 765 | 800 | // Add links setting|document|addon on plugins page. |
| 766 | 801 | add_filter( 'plugin_action_links_' . LP_PLUGIN_BASENAME, array( $this, 'plugin_links' ) ); |
| 767 | 802 | |
| 768 | - register_activation_hook( LP_PLUGIN_FILE, array( $this, 'on_activate' ) ); | |
| 769 | - register_deactivation_hook( LP_PLUGIN_FILE, array( $this, 'on_deactivate' ) ); | |
| 770 | - | |
| 771 | - add_action( | |
| 803 | + /*add_action( | |
| 772 | 804 | 'plugin_loaded', |
| 773 | 805 | function ( $plugin ) { |
| 774 | 806 | // For check wp_remote call normally of WP |
| 775 | 807 | if ( ! empty( LP_Request::get_param( 'lp_test_wp_remote' ) ) ) { |
| @@ -776,9 +808,9 @@ | ||
| 776 | 808 | echo '[TEST_REMOTE]'; |
| 777 | 809 | die; |
| 778 | 810 | } |
| 779 | 811 | } |
| 780 | - ); | |
| 812 | + );*/ | |
| 781 | 813 | |
| 782 | 814 | // Check require version thim-core on Backend. |
| 783 | 815 | if ( is_admin() ) { |
| 784 | 816 | add_action( 'before_thim_core_init', array( $this, 'check_thim_core_version_require' ) ); |
| @@ -807,9 +839,9 @@ | ||
| 807 | 839 | return; |
| 808 | 840 | } |
| 809 | 841 | |
| 810 | 842 | // Call active purchase code for site. |
| 811 | - LP_Manager_Addons::instance()->active_site( $addon_slug, $purchase_code_content ); | |
| 843 | + AddonService::instance()->active_site( $addon_slug, $purchase_code_content ); | |
| 812 | 844 | } |
| 813 | 845 | } |
| 814 | 846 | } |
| 815 | 847 | ); |
| @@ -853,21 +885,35 @@ | ||
| 853 | 885 | * @param array $links Array of action links |
| 854 | 886 | * |
| 855 | 887 | * @return array |
| 856 | 888 | * @since 4.3.11 |
| 857 | - * | |
| 889 | + * @version 1.0.1 | |
| 858 | 890 | */ |
| 859 | 891 | public function plugin_links( array $links ): array { |
| 860 | - $links[] = sprintf( '<a href="%s">%s</a>', admin_url( 'admin.php?page=learn-press-settings' ), __( 'Settings', 'learnpress' ) ); | |
| 861 | - $links[] = sprintf( '<a href="%s" target="_blank">%s</a>', LearnPress::$doc_link, __( 'Documentation', 'learnpress' ) ); | |
| 862 | - $links[] = sprintf( '<a href="%s" target="_blank">%s</a>', get_admin_url() . '/admin.php?page=learn-press-addons', __( 'Add-ons', 'learnpress' ) ); | |
| 892 | + $links[] = sprintf( | |
| 893 | + '<a href="%s">%s</a>', | |
| 894 | + esc_url_raw( admin_url( 'admin.php?page=learn-press-settings' ) ), | |
| 895 | + esc_html__( 'Settings', 'learnpress' ) | |
| 896 | + ); | |
| 897 | + $links[] = sprintf( | |
| 898 | + '<a href="%s" target="_blank">%s</a>', | |
| 899 | + esc_url_raw( LearnPress::$doc_link ), | |
| 900 | + esc_html__( 'Documentation', 'learnpress' ) | |
| 901 | + ); | |
| 902 | + $links[] = sprintf( | |
| 903 | + '<a href="%s" target="_blank">%s</a>', | |
| 904 | + esc_url_raw( admin_url( 'admin.php?page=learn-press-addons' ) ), | |
| 905 | + esc_html__( 'Add-ons', 'learnpress' ) | |
| 906 | + ); | |
| 863 | 907 | |
| 864 | 908 | return $links; |
| 865 | 909 | } |
| 866 | 910 | |
| 867 | 911 | /** |
| 868 | - * Trigger this function while activating Learnpress. | |
| 912 | + * Activation hook callback. | |
| 869 | 913 | * |
| 914 | + * Including creating database tables, default pages, registering CPTs and flushing rewrite rules. | |
| 915 | + * | |
| 870 | 916 | * @since 3.0.0 |
| 871 | 917 | * @version 4.1.4.1 |
| 872 | 918 | */ |
| 873 | 919 | public function on_activate() { |
| @@ -969,34 +1015,8 @@ | ||
| 969 | 1015 | $this->cart = LP_Cart::instance(); |
| 970 | 1016 | } |
| 971 | 1017 | |
| 972 | 1018 | return $this->cart; |
| 973 | - } | |
| 974 | - | |
| 975 | - /** | |
| 976 | - * Check type of request. | |
| 977 | - * | |
| 978 | - * @param string $type ajax, frontend or admin. | |
| 979 | - * | |
| 980 | - * @return bool | |
| 981 | - * @deprecated 4.2.9.4 | |
| 982 | - */ | |
| 983 | - public function is_request( $type ) { | |
| 984 | - _deprecated_function( __METHOD__, '4.2.9.4' ); | |
| 985 | - return false; | |
| 986 | - | |
| 987 | - switch ( $type ) { | |
| 988 | - case 'admin': | |
| 989 | - return is_admin(); | |
| 990 | - case 'ajax': | |
| 991 | - return defined( 'LP_DOING_AJAX' ); | |
| 992 | - case 'cron': | |
| 993 | - return defined( 'DOING_CRON' ); | |
| 994 | - case 'frontend': | |
| 995 | - return ( ! is_admin() || defined( 'LP_DOING_AJAX' ) ) && ! defined( 'DOING_CRON' ); | |
| 996 | - default: | |
| 997 | - return strtolower( $_SERVER['REQUEST_METHOD'] ) == $type; | |
| 998 | - } | |
| 999 | 1019 | } |
| 1000 | 1020 | |
| 1001 | 1021 | /** |
| 1002 | 1022 | * Get the plugin url. |