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