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
learnpress / learnpress.php

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

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