PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.2
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.2
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 4.2.1 4.2.1.1 All 137 releases
learnpress / learnpress.php

learnpress.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.2, at learnpress.php

1,104 lines 34.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Plugin Name: LearnPress
4 * Plugin URI: https://thimpress.com/learnpress
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 * Author: ThimPress
7 * Version: 4.4.2
8 * Author URI: http://thimpress.com
9 * Requires at least: 6.0
10 * Requires PHP: 7.4
11 * Text Domain: learnpress
12 * Domain Path: /languages/
13 *
14 * @package LearnPress
15 */
16
17 use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderListCoursesTemplate;
18 use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderCourseTemplate;
19 use LearnPress\TemplateHooks\CourseBuilder\Course\BuilderEditCourseTemplate;
20 use LearnPress\Ajax\AI\OpenAiAjax;
21 use LearnPress\Ajax\BuilderDashboardAjax;
22 use LearnPress\Ajax\CourseBuilder\CourseBuilderAjax;
23 use LearnPress\Ajax\EditCurriculumAjax;
24 use LearnPress\Ajax\EditQuestionAjax;
25 use LearnPress\Ajax\EditQuizAjax;
26 use LearnPress\Ajax\Order\ExportOrderCSVAjax;
27 use LearnPress\Ajax\LessonAjax;
28 use LearnPress\Ajax\LoadContentViaAjax;
29 use LearnPress\Ajax\AI\AIAssistantAjax;
30 use LearnPress\Ajax\MCP\McpApiKeysAjax;
31 use LearnPress\Ajax\Webhook\WebhooksAjax;
32 use LearnPress\Ajax\CourseBuilder\CBEditCourseAjax;
33 use LearnPress\Ajax\SendEmailAjax;
34 use LearnPress\Background\LPBackgroundTrigger;
35 use LearnPress\ExternalPlugin\Elementor\LPElementor;
36 use LearnPress\ExternalPlugin\RankMath\LPRankMath;
37 use LearnPress\ExternalPlugin\YoastSeo\LPYoastSeo;
38 use LearnPress\Gutenberg\GutenbergHandleMain;
39 use LearnPress\Ajax\Order\RefundOrderAjax;
40 use LearnPress\MCP\Abilities;
41 use LearnPress\MCP\Auth\ApiKeyAuthenticator;
42 use LearnPress\Models\CourseModel;
43 use LearnPress\Models\UserModel;
44 use LearnPress\Shortcodes\Course\FilterCourseShortcode;
45 use LearnPress\Shortcodes\CourseButtonShortcode;
46 use LearnPress\Shortcodes\CourseMaterialShortcode;
47 use LearnPress\Shortcodes\Courses\ListCoursesShortcode;
48 use LearnPress\Shortcodes\ListInstructorsShortcode;
49 use LearnPress\Shortcodes\SingleInstructorShortcode;
50 use LearnPress\TemplateHooks\Admin\AdminEditQizTemplate;
51 use LearnPress\TemplateHooks\Admin\AdminEditQuestionTemplate;
52 use LearnPress\TemplateHooks\Admin\AdminListStudentsEnrolled;
53 use LearnPress\TemplateHooks\Admin\AI\AdminCreateCourseAITemplate;
54 use LearnPress\TemplateHooks\Admin\AI\AdminEditCourseCurriculumWithAITemplate;
55 use LearnPress\TemplateHooks\Admin\AI\AdminEditWithAITemplate;
56 use LearnPress\TemplateHooks\Course\AdminEditCurriculumTemplate;
57 use LearnPress\TemplateHooks\Course\AdminEditSettingTemplate;
58 use LearnPress\TemplateHooks\Course\CourseMaterialTemplate;
59 use LearnPress\TemplateHooks\Course\FilterCourseTemplate;
60 use LearnPress\TemplateHooks\Course\ListCoursesRelatedTemplate;
61 use LearnPress\TemplateHooks\Course\ListCoursesTemplate;
62 use LearnPress\TemplateHooks\Course\SingleCourseClassicTemplate;
63 use LearnPress\TemplateHooks\Course\SingleCourseModernLayout;
64 use LearnPress\TemplateHooks\Course\SingleCourseOfflineTemplate;
65 use LearnPress\TemplateHooks\Course\SingleCourseTemplate;
66 use LearnPress\TemplateHooks\CourseBuilder\BuilderPopupTemplate;
67 use LearnPress\TemplateHooks\CourseBuilder\CourseBuilderTemplate;
68 use LearnPress\TemplateHooks\CourseBuilder\Dashboard\BuilderDashboardTemplate;
69 use LearnPress\TemplateHooks\CourseBuilder\Lesson\BuilderEditLessonTemplate;
70 use LearnPress\TemplateHooks\CourseBuilder\Lesson\BuilderLessonTemplate;
71 use LearnPress\TemplateHooks\CourseBuilder\Lesson\BuilderListLessonsTemplate;
72 use LearnPress\TemplateHooks\CourseBuilder\Question\BuilderEditQuestionTemplate;
73 use LearnPress\TemplateHooks\CourseBuilder\Question\BuilderListQuestionsTemplate;
74 use LearnPress\TemplateHooks\CourseBuilder\Question\BuilderQuestionTemplate;
75 use LearnPress\TemplateHooks\CourseBuilder\Quiz\BuilderEditQuizTemplate;
76 use LearnPress\TemplateHooks\CourseBuilder\Quiz\BuilderListQuizzesTemplate;
77 use LearnPress\TemplateHooks\CourseBuilder\Quiz\BuilderQuizTemplate;
78 use LearnPress\TemplateHooks\CourseBuilder\Settings\BuilderSettingsTemplate;
79 use LearnPress\TemplateHooks\Instructor\ListInstructorsTemplate;
80 use LearnPress\TemplateHooks\Instructor\SingleInstructorTemplate;
81 use LearnPress\TemplateHooks\Order\AdminOrderItemsTemplate;
82 use LearnPress\TemplateHooks\Order\AdminOrderListTemplate;
83 use LearnPress\TemplateHooks\Profile\ProfileCoursesTemplate;
84 use LearnPress\TemplateHooks\Profile\ProfileGeneralInfoTemplate;
85 use LearnPress\TemplateHooks\Profile\ProfileInstructorStatisticsTemplate;
86 use LearnPress\TemplateHooks\Profile\ProfileOrdersTemplate;
87 use LearnPress\TemplateHooks\Profile\ProfileOrderTemplate;
88 use LearnPress\TemplateHooks\Profile\ProfileQuizzesTemplate;
89 use LearnPress\TemplateHooks\Profile\ProfileStudentEnrolledTemplate;
90 use LearnPress\TemplateHooks\Profile\ProfileStudentStatisticsTemplate;
91 use LearnPress\TemplateHooks\Course\CourseAIAssistantTemplate;
92 use LearnPress\Widgets\LPRegisterWidget;
93 use LearnPress\WPGDPR\ErasePersonalData;
94 use LearnPress\WPGDPR\ExportPersonalData;
95 use LearnPress\Webhook\WebhookDispatcher;
96
97 defined( 'ABSPATH' ) || exit();
98
99 if ( ! class_exists( 'LearnPress' ) ) {
100 /**
101 * Class LearnPress
102 *
103 * Version 3.0.1
104 */
105 class LearnPress {
106 /**
107 * Current version of the plugin
108 *
109 * @var string
110 */
111 public $version = '';
112 /**
113 * Version database require, use for this LP source
114 *
115 * @var int
116 */
117 public $db_version = 5;
118
119 /**
120 * The single instance of the class
121 *
122 * @var LearnPress object
123 */
124 private static $_instance = null;
125
126 /**
127 * Store the session class
128 *
129 * @var LP_Session_Handler
130 */
131 public $session = null;
132
133 /**
134 * @var LP_Cart object
135 */
136 public $cart = false;
137
138 /**
139 * @var LP_Settings
140 */
141 public $settings = null;
142
143 /**
144 * @var array
145 */
146 public $query_vars = array();
147
148 /**
149 * @var array
150 */
151 public $global = array();
152
153 /**
154 * @var LP_Template
155 */
156 public $template = null;
157
158 /**
159 * @var LP_Core_API
160 */
161 public $api = null;
162
163 /**
164 * @var LP_Admin_Core_API
165 */
166 public $admin_api = null;
167
168 /**
169 * @var string
170 */
171 public $thim_core_version_require = '2.0.0';
172
173 public static $time_limit_default_of_sever = 0;
174
175 public static $doc_link = 'https://learnpresslms.com/docs/';
176
177 /**
178 * LearnPress constructor.
179 */
180 private function __construct() {
181 /*if ( isset( $_POST['action'] ) && 'heartbeat' === $_POST['action'] ) {
182 return;
183 }*/
184
185 try {
186 $this->prepare_before_handle();
187
188 if ( ! LP_Install::instance()->tables_install_done() ) {
189 return;
190 }
191
192 // Must handle in hook init of WordPress, when loaded plugins, theme, user.
193 add_action( 'init', [ $this, 'lp_main_handle' ], - 1000 );
194
195 // hooks .
196 $this->hooks();
197 } catch ( Throwable $e ) {
198 error_log( __METHOD__ . ': ' . $e->getMessage() );
199 }
200 }
201
202 /**
203 * Prepare before handle.
204 * 1.Load constants and includes files.
205 * 2.Get default time limit of server.
206 * 3.Update version of LP undefined.
207 *
208 * @return void
209 * @since 4.2.7.6
210 * @version 1.0.0
211 */
212 public function prepare_before_handle() {
213 // Define constant .
214 $this->plugin_defines();
215
216 self::$time_limit_default_of_sever = ini_get( 'max_execution_time' );
217
218 // Update for case compare version of LP if LEARNPRESS_VERSION undefined
219 $this->version = LEARNPRESS_VERSION;
220 if ( is_admin() ) {
221 $learn_press_version = get_option( 'learnpress_version', '' );
222 if ( $learn_press_version !== $this->version ) {
223 if ( empty( $learn_press_version ) ) { // Case user install new
224 // Set using modern layout for new installation.
225 update_option( 'learn_press_layout_single_course', 'modern' );
226 }
227
228 update_option( 'learnpress_version', $this->version );
229 }
230 }
231
232 // define table prefixes .
233 $this->define_tables();
234
235 // Include files .
236 $this->includes();
237 }
238
239 /**
240 * Define constant.
241 */
242 protected function plugin_defines() {
243 if ( ! defined( 'LP_PLUGIN_FILE' ) ) {
244 define( 'LP_PLUGIN_FILE', __FILE__ );
245 include_once 'inc/lp-constants.php';
246 }
247 }
248
249 /**
250 * Defines database table names.
251 */
252 public function define_tables() {
253 global $wpdb;
254
255 $tables = array(
256 'sessions',
257 'sections',
258 'section_items',
259 'user_items',
260 'user_itemmeta',
261 'user_item_results',
262 'order_items',
263 'order_itemmeta',
264 'quiz_questions',
265 'question_answers',
266 'question_answermeta',
267 );
268
269 foreach ( $tables as $short_name ) {
270 $table_name = $wpdb->prefix . LP_TABLE_PREFIX . $short_name;
271 $backward_key = 'learnpress_' . $short_name;
272 $wpdb->{$backward_key} = $table_name;
273 }
274 }
275
276 /**
277 * Includes needed files.
278 */
279 public function includes() {
280 include_once LP_PLUGIN_PATH . 'vendor/autoload.php';
281
282 // Include required files load anywhere, both frontend and backend.
283 $this->include_files_global();
284
285 // include files when LP ready run - after setup success .
286 if ( ! LP_Install::instance()->tables_install_done() ) {
287 return;
288 }
289
290 // Include required files Backend.
291 $this->include_files_admin();
292
293 // Include required files Frontend.
294 $this->include_files_frontend();
295
296 new LP_Query();
297 }
298
299 /**
300 * load files anywhere, both frontend and backend
301 *
302 * @return void
303 */
304 private function include_files_global() {
305
306 // Filter query .
307 include_once 'inc/Filters/class-lp-filter.php';
308 include_once 'inc/Filters/class-lp-post-type-filter.php';
309 include_once 'inc/Filters/class-lp-post-meta-filter.php';
310 include_once 'inc/Filters/class-lp-user-filter.php';
311 include_once 'inc/Filters/class-lp-course-filter.php';
312 include_once 'inc/Filters/class-lp-course-json-filter.php';
313 include_once 'inc/Filters/class-lp-order-filter.php';
314 include_once 'inc/Filters/class-lp-session-filter.php';
315 include_once 'inc/Filters/class-lp-section-filter.php';
316 include_once 'inc/Filters/class-lp-section-items-filter.php';
317 include_once 'inc/Filters/class-lp-question-filter.php';
318 include_once 'inc/Filters/class-lp-quiz-filter.php';
319 include_once 'inc/Filters/class-lp-user-items-filter.php';
320 include_once 'inc/Filters/class-lp-user-item-meta-filter.php';
321 include_once 'inc/Filters/class-lp-quiz-filter.php';
322 include_once 'inc/Filters/class-lp-quiz-questions-filter.php';
323 include_once 'inc/Filters/class-lp-question-answers-filter.php';
324 include_once 'inc/Filters/class-lp-question-answermeta-filter.php';
325
326 // Query Database .
327 include_once 'inc/Databases/class-lp-db.php';
328 include_once 'inc/Databases/class-lp-course-json-db.php';
329 include_once 'inc/Databases/class-lp-order-db.php';
330 include_once 'inc/Databases/class-lp-post-db.php';
331 include_once 'inc/Databases/class-lp-post-meta-db.php';
332 include_once 'inc/Databases/class-lp-user-db.php';
333 include_once 'inc/Databases/class-lp-course-db.php';
334 include_once 'inc/Databases/class-lp-lesson-db.php';
335 include_once 'inc/Databases/class-lp-section-db.php';
336 include_once 'inc/Databases/class-lp-section-items-db.php';
337 include_once 'inc/Databases/class-lp-quiz-db.php';
338 include_once 'inc/Databases/class-lp-quiz-questions-db.php';
339 include_once 'inc/Databases/class-lp-question-answers-db.php';
340 include_once 'inc/Databases/class-lp-sessions-db.php';
341 include_once 'inc/Databases/class-lp-question-db.php';
342 include_once 'inc/Databases/class-lp-user-items-db.php';
343 include_once 'inc/Databases/class-lp-user-item-meta-db.php';
344 include_once 'inc/Databases/class-lp-user-item-results-db.php';
345 include_once 'inc/Databases/class-thim-cache-db.php';
346 include_once 'inc/Databases/class-lp-material-db.php';
347 include_once 'inc/Databases/class-lp-statistics-db.php';
348
349 // File system .
350 include_once 'inc/class-lp-file-system.php';
351
352 // File helper
353 include_once 'inc/class-lp-helper.php';
354
355 // Template Hooks.
356 ListCoursesTemplate::instance();
357 ListCoursesRelatedTemplate::instance();
358 ListInstructorsTemplate::instance();
359 SingleCourseTemplate::instance();
360 SingleCourseOfflineTemplate::instance();
361 SingleCourseModernLayout::instance();
362 SingleCourseClassicTemplate::instance();
363 SingleInstructorTemplate::instance();
364 ProfileInstructorStatisticsTemplate::instance();
365 ProfileStudentStatisticsTemplate::instance();
366 ProfileOrdersTemplate::instance();
367 ProfileOrderTemplate::instance();
368 ProfileGeneralInfoTemplate::instance();
369 FilterCourseTemplate::instance();
370 ProfileQuizzesTemplate::instance();
371 CourseBuilderTemplate::instance();
372 BuilderCourseTemplate::instance();
373 BuilderListCoursesTemplate::instance();
374 BuilderDashboardTemplate::instance();
375 BuilderSettingsTemplate::instance();
376 BuilderDashboardAjax::instance();
377 BuilderEditCourseTemplate::instance();
378 BuilderLessonTemplate::instance();
379 BuilderListLessonsTemplate::instance();
380 BuilderEditLessonTemplate::instance();
381 BuilderQuizTemplate::instance();
382 BuilderListQuizzesTemplate::instance();
383 BuilderEditQuizTemplate::instance();
384 BuilderQuestionTemplate::instance();
385 BuilderListQuestionsTemplate::instance();
386 BuilderEditQuestionTemplate::instance();
387 BuilderPopupTemplate::instance();
388 ProfileCoursesTemplate::instance();
389 ProfileStudentEnrolledTemplate::instance();
390
391 // Admin template hooks.
392 AdminEditCurriculumTemplate::instance();
393 AdminEditSettingTemplate::instance();
394 AdminEditQizTemplate::instance();
395 AdminEditQuestionTemplate::instance();
396 CourseMaterialTemplate::instance();
397 CourseAIAssistantTemplate::instance();
398 AdminOrderItemsTemplate::instance();
399 AdminOrderListTemplate::instance();
400 AdminCreateCourseAITemplate::instance();
401 AdminEditWithAITemplate::instance();
402 AdminEditCourseCurriculumWithAITemplate::instance();
403 AdminListStudentsEnrolled::instance();
404 // WP GDPR
405 ErasePersonalData::instance();
406 ExportPersonalData::instance();
407
408 // Models
409 include_once 'inc/Models/class-lp-rest-response.php';
410 include_once 'inc/Models/steps/class-lp-group-step.php';
411 include_once 'inc/Models/steps/class-lp-step.php';
412 include_once 'inc/Models/class-lp-course-extra-info-fast-query-model.php';
413
414 // Handle steps.
415 include_once 'inc/handle-steps/class-lp-handle-steps.php';
416 include_once 'inc/handle-steps/class-lp-handle-upgrade-db-steps.php';
417
418 // LP Cache
419 include_once 'inc/cache/class-lp-cache.php';
420 include_once 'inc/cache/class-lp-courses-cache.php';
421 include_once 'inc/cache/class-lp-course-cache.php';
422 include_once 'inc/cache/class-lp-quiz-cache.php';
423 include_once 'inc/cache/class-lp-question-cache.php';
424 include_once 'inc/cache/class-lp-session-cache.php';
425 include_once 'inc/cache/class-lp-settings-cache.php';
426 include_once 'inc/cache/class-lp-user-items-cache.php';
427
428 // Background processes.
429 LPBackgroundTrigger::instance();
430 include_once 'inc/libraries/wp-background-process/wp-background-processing.php';
431 include_once 'inc/background-process/abstract-lp-async-request.php';
432 //include_once 'inc/background-process/abstract-lp-async-task.php';
433 include_once 'inc/background-process/class-lp-background-single-course.php';
434 include_once 'inc/background-process/class-lp-background-single-email.php';
435
436 // Assets object
437 include_once 'inc/class-lp-asset-key.php';
438 include_once 'inc/abstracts/abstract-assets.php';
439
440 // Debug class
441 include_once 'inc/class-lp-debug.php';
442
443 include_once 'inc/class-lp-settings.php';
444 include_once 'inc/abstract-settings.php';
445 include_once 'inc/settings/abstract-settings-page.php';
446 include_once 'inc/settings/class-lp-settings-courses.php';
447 include_once 'inc/class-lp-global.php';
448 include_once 'inc/class-lp-datetime.php';
449
450 // Register custom-post-type and taxonomies .
451 /*include_once 'inc/custom-post-types/abstract.php';
452 include_once 'inc/custom-post-types/course.php';
453 include_once 'inc/custom-post-types/lesson.php';
454 include_once 'inc/custom-post-types/quiz.php';
455 include_once 'inc/custom-post-types/question.php';
456 include_once 'inc/custom-post-types/order.php';*/
457
458 include_once 'inc/interfaces/interface-curd.php';
459 include_once 'inc/abstracts/abstract-array-access.php';
460 include_once 'inc/abstracts/abstract-object-data.php';
461 include_once 'inc/abstracts/abstract-post-data.php';
462
463 include_once 'inc/curds/class-lp-course-curd.php';
464 include_once 'inc/curds/class-lp-section-curd.php';
465 include_once 'inc/curds/class-lp-lesson-curd.php';
466 include_once 'inc/curds/class-lp-quiz-curd.php';
467 include_once 'inc/curds/class-lp-question-curd.php';
468 include_once 'inc/curds/class-lp-order-curd.php';
469 include_once 'inc/curds/class-lp-user-curd.php';
470 include_once 'inc/curds/class-lp-user-item-curd.php';
471
472 include_once 'inc/course/class-lp-course-item.php';
473 include_once 'inc/question/class-lp-question.php';
474 include_once 'inc/course/class-lp-course-section.php';
475 include_once 'inc/course/class-lp-course-no-required-enroll.php';
476 include_once 'inc/user-item/class-lp-user-item.php';
477 include_once 'inc/user-item/class-lp-user-item-course.php';
478
479 include_once 'inc/lp-deprecated.php'; // Will remove if Eduma and guest update all 4.0.0
480 include_once 'inc/lp-core-functions.php';
481 include_once 'inc/class-lp-autoloader.php';
482
483 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.
484 include_once 'inc/class-lp-request-handler.php';
485
486 include_once 'inc/admin/helpers/class-lp-plugins-helper.php';
487
488 // Todo: tungnx check those files.
489 include_once 'inc/abstracts/abstract-object-query.php';
490 include_once 'inc/class-lp-course-query.php';
491 include_once 'inc/abstracts/abstract-addon.php';
492 include_once 'inc/class-lp-thumbnail-helper.php';
493 include_once 'inc/cache.php';
494
495 // Class handle check db of LP need to upgrade?
496 include_once 'inc/admin/class-lp-updater.php';
497
498 include_once 'inc/course/lp-course-functions.php';
499 include_once 'inc/course/abstract-course.php';
500 include_once 'inc/course/class-lp-course.php';
501 include_once 'inc/quiz/lp-quiz-functions.php';
502 include_once 'inc/quiz/class-lp-quiz.php';
503 //include_once 'inc/lesson/lp-lesson-functions.php';
504 include_once 'inc/order/lp-order-functions.php';
505 include_once 'inc/order/class-lp-order.php';
506
507 include_once 'inc/user/lp-user-functions.php';
508 include_once 'inc/user/class-lp-user-factory.php';
509 WebhookDispatcher::instance();
510 include_once 'inc/user/abstract-lp-user.php';
511 include_once 'inc/user/class-lp-user.php';
512 include_once 'inc/user/class-lp-profile.php';
513 include_once 'inc/user-item/class-lp-user-item.php';
514 include_once 'inc/user-item/class-lp-user-item-course.php';
515 include_once 'inc/user-item/class-lp-user-item-quiz.php';
516 include_once 'inc/user-item/class-lp-quiz-results.php';
517
518 // Shortcodes.
519 SingleInstructorShortcode::instance();
520 ListInstructorsShortcode::instance();
521 CourseMaterialShortcode::instance();
522 CourseButtonShortcode::instance();
523 FilterCourseShortcode::instance();
524 ListCoursesShortcode::instance();
525 //ListCourseRecentShortcode::instance();
526 include_once 'inc/class-lp-shortcodes.php';
527
528 // include template functions .
529 include_once 'inc/lp-template-functions.php';
530 include_once 'inc/templates/abstract-template.php';
531 //include_once 'inc/class-lp-template.php';
532
533 // Cart
534 include_once 'inc/cart/class-lp-cart.php';
535 include_once 'inc/cart/lp-cart-functions.php';
536
537 // Block Templates
538 //include_once 'inc/block-template/class-abstract-block-template.php';
539 //include_once 'inc/block-template/class-block-template-handle.php';
540 GutenbergHandleMain::instance();
541
542 // API
543 include_once 'inc/abstracts/abstract-rest-api.php';
544 include_once 'inc/abstracts/abstract-rest-controller.php';
545 include_once 'inc/rest-api/class-lp-core-api.php';
546 include_once 'inc/rest-api/class-lp-admin-core-api.php';
547
548 /** Jwt */
549 include_once 'inc/jwt/class-jwt-auth.php';
550
551 LPRegisterWidget::instance();
552 include_once 'inc/class-lp-widget.php';
553 include_once 'inc/lp-widget-functions.php';
554
555 // TODO: update frontend editor before move to function include_files_admin.
556 include_once 'inc/admin/views/meta-boxes/class-lp-meta-box.php';
557
558 include_once 'inc/class-lp-page-controller.php';
559 LP_Page_Controller::instance();
560
561 include_once 'inc/gateways/class-lp-gateway-abstract.php';
562 include_once 'inc/gateways/subscriptions/class-lp-subscription-manager.php';
563 include_once 'inc/gateways/class-lp-gateways.php';
564 }
565
566 /**
567 * Include file run on backend
568 */
569 private function include_files_admin() {
570 if ( ! is_admin() ) {
571 return;
572 }
573
574 include_once 'inc/admin/class-lp-admin-ajax.php';
575
576 include_once 'inc/admin/class-lp-admin-notice.php';
577
578 // File handle install LP
579 include_once 'inc/class-lp-install.php';
580
581 // Meta box helper
582 include_once 'inc/admin/meta-box/class-lp-meta-box-helper.php';
583
584 // include_once 'inc/admin/class-lp-admin.php';
585 // include_once 'inc/admin/settings/abstract-settings-page.php';
586 }
587
588 /**
589 * Include file run on frontend
590 */
591 private function include_files_frontend() {
592 if ( is_admin() ) {
593 return;
594 }
595
596 include_once 'inc/class-lp-assets.php';
597
598 include_once 'inc/course/class-model-user-can-view-course-item.php';
599
600 include_once 'inc/class-lp-ajax.php';
601
602 include_once 'inc/class-lp-session-handler.php';
603 }
604
605 /**
606 * Main instance of LearnPress.
607 * Must load on "init" hook of WordPress.
608 * 1. Load text domain.
609 * 2. Handle lp ajax.
610 *
611 * @return void
612 * @version 4.2.7.6
613 * @version 1.0.2
614 */
615 public function lp_main_handle() {
616 try {
617 // Load text domain.
618 $this->load_plugin_text_domain();
619
620 // Register custom post type and taxonomies .
621 include_once 'inc/custom-post-types/abstract.php';
622 include_once 'inc/custom-post-types/course.php';
623 include_once 'inc/custom-post-types/lesson.php';
624 include_once 'inc/custom-post-types/quiz.php';
625 include_once 'inc/custom-post-types/question.php';
626 include_once 'inc/custom-post-types/order.php';
627
628 // Polylang
629 if ( defined( 'POLYLANG_VERSION' ) ) {
630 include_once 'inc/ExternalPlugin/Polylang/class-lp-polylang.php';
631 LP_Polylang::instance();
632 }
633
634 // For plugin Elementor
635 if ( defined( 'ELEMENTOR_VERSION' ) ) {
636 LPElementor::instance();
637 }
638
639 // For plugin WPSEO
640 if ( defined( 'WPSEO_FILE' ) ) {
641 LPYoastSeo::instance();
642 }
643
644 // For plugin RankMath
645 if ( defined( 'RANK_MATH_VERSION' ) ) {
646 LPRankMath::instance();
647 }
648
649 $this->api = new LP_Core_API();
650 $this->admin_api = new LP_Admin_Core_API();
651 $this->get_session();
652 $this->settings = $this->settings();
653 $this->get_cart();
654
655 // Init emails
656 LP_Emails::instance();
657 // Email hook notify
658 include_once 'inc/emails/class-lp-email-hooks.php';
659
660 if ( is_admin() ) {
661 $this->check_addons_version_valid();
662
663 include_once 'inc/admin/class-lp-admin.php';
664 }
665
666 // let third parties know that we're ready .
667 do_action( 'learn-press/ready' );
668
669 // For addon sorting choice old <= v4.0.1
670 /*if ( class_exists( 'LP_Addon_Sorting_Choice_Preload' ) ) {
671 if ( version_compare( LP_ADDON_SORTING_CHOICE_VER, '4.0.1', '<=' ) ) {
672 $lp_addon_sorting_choice = new LP_Addon_Sorting_Choice();
673 $lp_addon_sorting_choice->init();
674 }
675 }*/
676
677 /**
678 * Init gateways, to load all payment gateways, catch callback.
679 * Must be call after learn-press/ready to register hook of addon.
680 */
681 LP_Gateways::instance();
682
683 /**
684 * Fixed temporary for emails of Announcement v4.0.6, Assignment v4.1.1 addons.
685 * @since 4.2.7.4
686 * When 2 addons update to new version, will remove this code.
687 */
688 /*if ( class_exists( 'LP_Addon_Announcements_Preload' ) ) {
689 if ( version_compare( LP_ADDON_ANNOUNCEMENTS_VER, '4.0.6', '<=' ) ) {
690 $addon_announcement = LP_Addon_Announcements_Preload::$addon;
691 $addon_announcement->emails_setting();
692 }
693 }*/
694 /*if ( class_exists( 'LP_Addon_Assignment_Preload' ) ) {
695 if ( version_compare( LP_ADDON_ASSIGNMENT_VER, '4.1.1', '<=' ) ) {
696 $addon_assignment = LP_Addon_Assignment_Preload::$addon;
697 $addon_assignment->emails_setting();
698 }
699 }*/
700 } catch ( Throwable $e ) {
701 LP_Debug::error_log( $e );
702 }
703 }
704
705 /**
706 * Check version addons valid version require.
707 * If not valid will be to deactivate.
708 * Reload page, so not affect to hook "learn-press/ready"
709 */
710 public function check_addons_version_valid() {
711 $addons_valid = true;
712 $plugins = get_option( 'active_plugins' );
713
714 $list_lp_addon_activated = preg_grep( '/^learnpress-.*/i', $plugins );
715 foreach ( $list_lp_addon_activated as $lp_addon ) {
716 $lp_addon_info = get_file_data(
717 WP_PLUGIN_DIR . '/' . $lp_addon,
718 array(
719 'Require_LP_Version' => 'Require_LP_Version',
720 'Version' => 'Version',
721 )
722 );
723
724 $lp_addon_version = $lp_addon_info['Version'];
725
726 $addon = new LP_Addon();
727 $addon->version = $lp_addon_version;
728 $addon->plugin_base = $lp_addon;
729 $addon->require_version = $lp_addon_info['Require_LP_Version'];
730 $addon_valid = $addon->check_require_version_addon();
731
732 if ( $addons_valid ) {
733 //$addon_valid = $addon->check_require_version_lp();
734 }
735
736 if ( ! $addon_valid ) {
737 $addons_valid = false;
738 }
739 }
740 }
741
742 /**
743 * Initial common hooks
744 */
745 public function hooks() {
746 add_action( 'init', array( $this, 'maybe_init_mcp_abilities' ), 20 );
747
748 /**
749 * Handle lp ajax.
750 * Set priority after register_post_type to register capabilities for post type of LP.
751 */
752 add_action(
753 'init',
754 function () {
755 LoadContentViaAjax::catch_lp_ajax();
756 LessonAjax::catch_lp_ajax();
757 EditCurriculumAjax::catch_lp_ajax();
758 EditQuizAjax::catch_lp_ajax();
759 EditQuestionAjax::catch_lp_ajax();
760 SendEmailAjax::catch_lp_ajax();
761 RefundOrderAjax::catch_lp_ajax();
762 CourseBuilderAjax::catch_lp_ajax();
763 OpenAiAjax::catch_lp_ajax();
764 AIAssistantAjax::catch_lp_ajax();
765 ExportOrderCSVAjax::catch_lp_ajax();
766 McpApiKeysAjax::catch_lp_ajax();
767 WebhooksAjax::catch_lp_ajax();
768 CBEditCourseAjax::catch_lp_ajax();
769
770 do_action( 'learn-press/register-ajax-handlers' );
771 },
772 11
773 );
774
775 // Add links setting|document|addon on plugins page.
776 add_filter( 'plugin_action_links_' . LP_PLUGIN_BASENAME, array( $this, 'plugin_links' ) );
777
778 register_activation_hook( LP_PLUGIN_FILE, array( $this, 'on_activate' ) );
779 register_deactivation_hook( LP_PLUGIN_FILE, array( $this, 'on_deactivate' ) );
780
781 add_action(
782 'plugin_loaded',
783 function ( $plugin ) {
784 // For check wp_remote call normally of WP
785 if ( ! empty( LP_Request::get_param( 'lp_test_wp_remote' ) ) ) {
786 echo '[TEST_REMOTE]';
787 die;
788 }
789 }
790 );
791
792 // Check require version thim-core on Backend.
793 if ( is_admin() ) {
794 add_action( 'before_thim_core_init', array( $this, 'check_thim_core_version_require' ) );
795 }
796
797 // Save key purchase addon when install via file download from Thimpress.
798 add_action(
799 'upgrader_process_complete',
800 function ( $plugin_upgrader ) {
801 if ( ! empty( $plugin_upgrader->result ) ) {
802 $res = $plugin_upgrader->result;
803 $path_source = $res['destination'] ?? '';
804 if ( empty( $path_source ) ) {
805 return;
806 }
807
808 $key_purchase_path = realpath( $path_source . '/purchase-code.txt' );
809 if ( file_exists( $key_purchase_path ) ) {
810 $purchase_code_content = file_get_contents( $key_purchase_path );
811 if ( empty( $purchase_code_content ) ) {
812 return;
813 }
814
815 $addon_slug = $res['destination_name'] ?? '';
816 if ( empty( $addon_slug ) ) {
817 return;
818 }
819
820 // Call active purchase code for site.
821 LP_Manager_Addons::instance()->active_site( $addon_slug, $purchase_code_content );
822 }
823 }
824 }
825 );
826
827 // Clear cache UserModel when save user.
828 add_action(
829 'wp_update_user',
830 function ( $user_id ) {
831 $user = UserModel::find( $user_id, true );
832 $user->clean_caches();
833 }
834 );
835
836 // For temporary fix issue security of wp comments. Is it error of WP, not LP, LP only call to comments_template function.
837 add_filter(
838 'comments_array',
839 function ( $comments_flat, $post_id ) {
840 // Check if post type is course or item's course (lesson, quiz...)
841 $post_type = get_post_type( $post_id );
842 $course_item_types = CourseModel::item_types_support();
843 $course_item_types[] = LP_COURSE_CPT;
844 if ( ! in_array( $post_type, $course_item_types ) ) {
845 return $comments_flat;
846 }
847
848 foreach ( $comments_flat as $key => $comment ) {
849 $comment->comment_content = wp_kses_post( $comment->comment_content );
850 $comments_flat[ $key ] = $comment;
851 }
852
853 return $comments_flat;
854 },
855 10,
856 2
857 );
858 }
859
860 /**
861 * Add links to Documentation and Extensions in plugin's list of action links
862 *
863 * @param array $links Array of action links
864 *
865 * @return array
866 * @since 4.3.11
867 *
868 */
869 public function plugin_links( array $links ): array {
870 $links[] = sprintf( '<a href="%s">%s</a>', admin_url( 'admin.php?page=learn-press-settings' ), __( 'Settings', 'learnpress' ) );
871 $links[] = sprintf( '<a href="%s" target="_blank">%s</a>', LearnPress::$doc_link, __( 'Documentation', 'learnpress' ) );
872 $links[] = sprintf( '<a href="%s" target="_blank">%s</a>', get_admin_url() . '/admin.php?page=learn-press-addons', __( 'Add-ons', 'learnpress' ) );
873
874 return $links;
875 }
876
877 /**
878 * Trigger this function while activating Learnpress.
879 *
880 * @since 3.0.0
881 * @version 4.1.4.1
882 */
883 public function on_activate() {
884 LP_Install::instance()->on_activate();
885 }
886
887 /**
888 * Trigger this function while deactivating Learnpress.
889 *
890 * $since 3.0.0
891 *
892 * @hook learn_press_deactivate
893 */
894 public function on_deactivate() {
895 do_action( 'learn-press/deactivate', $this );
896 }
897
898 /**
899 * Conditionally bootstrap MCP abilities.
900 *
901 * @return void
902 */
903 public function maybe_init_mcp_abilities() {
904 if ( LP_Settings::get_option( 'enable_mcp_integration', 'no' ) !== 'yes' ) {
905 return;
906 }
907
908 ApiKeyAuthenticator::init();
909 Abilities::init();
910 }
911
912 /**
913 * Handle load text domain for LearnPress.
914 *
915 * @since 4.2.7.4
916 * @version 1.0.1
917 */
918 public function load_plugin_text_domain() {
919 /*$locale = determine_locale();
920 $locale = apply_filters( 'plugin_locale', $locale, 'learnpress' );
921
922 $plugin_translation_path = WP_LANG_DIR . '/plugins/learnpress-' . $locale . '.mo';
923 $custom_translation_path = WP_LANG_DIR . '/learnpress/learnpress-' . $locale . '.mo';
924 if ( is_readable( $custom_translation_path ) ) {
925 unload_textdomain( LP_TEXT_DOMAIN );
926 load_textdomain( LP_TEXT_DOMAIN, $custom_translation_path );
927 load_textdomain( LP_TEXT_DOMAIN, $plugin_translation_path );
928 }*/
929
930 load_plugin_textdomain( LP_TEXT_DOMAIN, false, LP_PLUGIN_FOLDER_NAME . '/languages' );
931 }
932
933 /**
934 * Get instance of class LP_Template.
935 *
936 * @param string $type
937 *
938 * @return LP_Template_Course|LP_Template_Profile|LP_Template_General|LP_Abstract_Template|LP_Template
939 *
940 * @throws Exception
941 * @since 3.3.0
942 */
943 public function template( $type = '' ) {
944 $this->template = LP_Template::instance();
945 $templates = (array) $this->template->get_templates();
946
947 return $templates[ $type ] ?? $this->template;
948 }
949
950 /**
951 * Get session object instance.
952 *
953 * @return mixed
954 */
955 public function get_session() {
956 if ( ! $this->session ) {
957 $this->session = LP_Session_Handler::instance();
958 }
959
960 return $this->session;
961 }
962
963 /**
964 * Get settings object instance.
965 *
966 * @return bool|LP_Settings
967 */
968 public function settings() {
969 return LP_Settings::instance();
970 }
971
972 /**
973 * Get cart object instance for online learning market.
974 *
975 * @return LP_Cart
976 */
977 public function get_cart(): LP_Cart {
978 if ( ! $this->cart ) {
979 $this->cart = LP_Cart::instance();
980 }
981
982 return $this->cart;
983 }
984
985 /**
986 * Get the plugin url.
987 *
988 * @param string $sub_dir
989 *
990 * @return string
991 */
992 public function plugin_url( $sub_dir = '' ) {
993 return LP_PLUGIN_URL . ( $sub_dir ? "{$sub_dir}" : '' );
994 }
995
996 /**
997 * Get the plugin path.
998 *
999 * @param string $sub_dir
1000 *
1001 * @return string
1002 */
1003 public function plugin_path( $sub_dir = '' ) {
1004 return LP_PLUGIN_PATH . ( $sub_dir ? "{$sub_dir}" : '' );
1005 }
1006
1007 /**
1008 * Get checkout object instance
1009 *
1010 * @return LP_Checkout
1011 */
1012 public function checkout() {
1013 return LP_Checkout::instance();
1014 }
1015
1016 /**
1017 * Short way to return image file is located in LearnPress directory.
1018 *
1019 * @param string
1020 *
1021 * @return string
1022 */
1023 public function image( $file ) {
1024 if ( ! preg_match( '/.(jpg|png)$/', $file ) ) {
1025 $file .= '.jpg';
1026 }
1027
1028 return $this->plugin_url( "assets/images/{$file}" );
1029 }
1030
1031 /**
1032 * Check require version thim-core
1033 */
1034 public function check_thim_core_version_require() {
1035 // Get thim-core info for LP check .
1036 include_once ABSPATH . 'wp-admin/includes/plugin.php';
1037 $thim_core_info = get_file_data(
1038 WP_PLUGIN_DIR . '/thim-core/thim-core.php',
1039 array(
1040 'Name' => 'Plugin Name',
1041 'Require_LP_Version' => 'Require_LP_Version',
1042 'Version' => 'Version',
1043 )
1044 );
1045
1046 if ( version_compare( $this->thim_core_version_require, $thim_core_info['Version'], '>' ) ) {
1047 deactivate_plugins( 'thim-core/thim-core.php' );
1048
1049 if ( isset( $_GET['activate'] ) ) {
1050 unset( $_GET['activate'] );
1051 }
1052
1053 $message = sprintf(
1054 '%s %s You can download %s. Read guide on %s',
1055 'LP4 require version Thim-core:',
1056 $this->thim_core_version_require,
1057 '<a href="https://thimpresswp.github.io/thim-core/thim-core.zip">latest version</a>',
1058 '<a href="https://docspress.thimpress.com/upgrade-database-how-to-fix-some-issue/">here</a>'
1059 );
1060 ?>
1061 <div class="notice notice-error">
1062 <p><?php echo wp_kses_post( $message ); ?></p>
1063 </div>
1064 <?php
1065 die;
1066 }
1067 }
1068
1069 /**
1070 * Main plugin instance.
1071 *
1072 * @return LearnPress
1073 */
1074 public static function instance() {
1075 if ( is_null( self::$_instance ) ) {
1076 self::$_instance = new self();
1077 }
1078
1079 return self::$_instance;
1080 }
1081 }
1082 }
1083
1084 /**
1085 * Short way to load main instance of plugin
1086 *
1087 * @return LearnPress
1088 * @since 1.0
1089 * @author thimpress
1090 */
1091 function LP() {
1092 return LearnPress::instance();
1093 }
1094
1095 /**
1096 * Done! entry point of the plugin
1097 * Create new instance of LearnPress and put it to global
1098 */
1099 $GLOBALS['LearnPress'] = LearnPress::instance();
1100
1101 // Load template hooks here, before theme add hooks remove.
1102 // Load here because this file call LearnPress::instance(), loop call.
1103 require_once 'inc/lp-template-hooks.php';
1104