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