Below is a differential between the unpatched vulnerable code and the patched update, for reference.
--- a/learnpress/config/block-templates.php
+++ b/learnpress/config/block-templates.php
@@ -1,14 +0,0 @@
-<?php
-$blog_template_path = LP_PLUGIN_PATH . 'inc/block-template/';
-require_once $blog_template_path . 'class-block-template-archive-course.php';
-require_once $blog_template_path . 'class-block-template-single-course.php';
-require_once $blog_template_path . 'class-block-template-item-curriculum-course.php';
-
-return apply_filters(
- 'learn-press/config/block-templates',
- array(
- new Block_Template_Archive_Course(),
- new Block_Template_Single_Course(),
- //new Block_Template_Item_Curriculum_Course(), // When handle item correct post type, uncomment this line, currently item show is post type course.
- )
-);
--- a/learnpress/config/profile-tabs.php
+++ b/learnpress/config/profile-tabs.php
@@ -49,7 +49,7 @@
'priority' => 30,
),
'enrolled-students' => array(
- 'title' => __( 'Enrolled Students', 'learnpress' ),
+ 'title' => __( 'Students', 'learnpress' ),
'slug' => 'enrolled-students',
'callback' => [ ProfileStudentEnrolledTemplate::class, 'tab_content' ],
'priority' => 35,
--- a/learnpress/inc/Ajax/AI/OpenAiAjax.php
+++ b/learnpress/inc/Ajax/AI/OpenAiAjax.php
@@ -7,6 +7,9 @@
use LearnPressAjaxAbstractAjax;
use LearnPressHelpersConfig;
use LearnPressHelpersTemplate;
+use LearnPressModelsCourseModel;
+use LearnPressModelsCoursePostModel;
+use LearnPressModelsPostModel;
use LearnPressModelsQuizPostModel;
use LearnPressModelsUserModel;
use LearnPressServicesCourseService;
@@ -434,7 +437,7 @@
* Upload image to media and set as feature image for post
*
* @since 4.3.0
- * @version 1.0.0
+ * @version 1.0.1
*/
public function openai_apply_image_feature() {
$response = new LP_REST_Response();
@@ -461,6 +464,29 @@
throw new Exception( __( 'Invalid post ID.', 'learnpress' ) );
}
+ // Check permission
+ $post_type = get_post_type( $post_id );
+ if ( $post_type === LP_COURSE_CPT ) {
+ $coursePostModel = CoursePostModel::find( $post_id, true );
+ if ( ! $coursePostModel ) {
+ throw new Exception( __( 'Invalid course ID.', 'learnpress' ) );
+ }
+
+ if ( ! $coursePostModel->check_capabilities_update() ) {
+ throw new Exception(
+ __( 'You do not have permission to perform this action.', 'learnpress' )
+ );
+ }
+ } else {
+ $course_item_types = CourseModel::item_types_support();
+ if ( ! in_array( $post_type, $course_item_types ) ) {
+ throw new Exception( __( 'Invalid post type.', 'learnpress' ) );
+ }
+
+ $postModel = PostModel::find_by_id( $post_id, true );
+ $postModel->check_capabilities_update_item_course();
+ }
+
if ( ! function_exists( 'media_handle_sideload' ) ) {
require_once ABSPATH . 'wp-admin/includes/media.php';
require_once ABSPATH . 'wp-admin/includes/file.php';
--- a/learnpress/inc/ExternalPlugin/Elementor/Widgets/Course/Dynamic/CourseAddressDynamicElementor.php
+++ b/learnpress/inc/ExternalPlugin/Elementor/Widgets/Course/Dynamic/CourseAddressDynamicElementor.php
@@ -1,48 +0,0 @@
-<?php
-/**
- * Class CourseLevelDynamicElementor
- *
- * Dynamic course level elementor.
- *
- * @since 4.2.3.5
- * @version 1.0.0
- */
-
-namespace LearnPressExternalPluginElementorWidgetsCourseDynamic;
-use ElementorCoreDynamicTagsTag;
-use LearnPressExternalPluginElementorLPDynamicElementor;
-use LearnPressModelsCourseModel;
-use LearnPressTemplateHooksCourseSingleCourseTemplate;
-use Throwable;
-
-defined( 'ABSPATH' ) || exit;
-
-class CourseAddressDynamicElementor extends Tag {
- use LPDynamicElementor;
-
- public function __construct( array $data = [] ) {
- $this->lp_dynamic_title = 'Course Address';
- $this->lp_dynamic_name = 'course-address';
- parent::__construct( $data );
- }
-
- public function render() {
- $singleCourseTemplate = SingleCourseTemplate::instance();
-
- try {
- $course = $this->get_course();
- if ( ! $course ) {
- return;
- }
-
- $course = CourseModel::find( $course->get_id() );
- if ( ! $course ) {
- return;
- }
-
- echo $singleCourseTemplate->html_address( $course );
- } catch ( Throwable $e ) {
- error_log( $e->getMessage() );
- }
- }
-}
--- a/learnpress/inc/ExternalPlugin/Elementor/Widgets/Course/Dynamic/CourseDeliverTypeDynamicElementor.php
+++ b/learnpress/inc/ExternalPlugin/Elementor/Widgets/Course/Dynamic/CourseDeliverTypeDynamicElementor.php
@@ -1,48 +0,0 @@
-<?php
-/**
- * Class CourseLevelDynamicElementor
- *
- * Dynamic course level elementor.
- *
- * @since 4.2.3.5
- * @version 1.0.0
- */
-
-namespace LearnPressExternalPluginElementorWidgetsCourseDynamic;
-use ElementorCoreDynamicTagsTag;
-use LearnPressExternalPluginElementorLPDynamicElementor;
-use LearnPressModelsCourseModel;
-use LearnPressTemplateHooksCourseSingleCourseTemplate;
-use Throwable;
-
-defined( 'ABSPATH' ) || exit;
-
-class CourseDeliverTypeDynamicElementor extends Tag {
- use LPDynamicElementor;
-
- public function __construct( array $data = [] ) {
- $this->lp_dynamic_title = 'Course Deliver Type';
- $this->lp_dynamic_name = 'course-deliver-type';
- parent::__construct( $data );
- }
-
- public function render() {
- $singleCourseTemplate = SingleCourseTemplate::instance();
-
- try {
- $course = $this->get_course();
- if ( ! $course ) {
- return;
- }
-
- $course = CourseModel::find( $course->get_id() );
- if ( ! $course ) {
- return;
- }
-
- echo $singleCourseTemplate->html_deliver_type( $course );
- } catch ( Throwable $e ) {
- error_log( $e->getMessage() );
- }
- }
-}
--- a/learnpress/inc/Shortcodes/class-lp-shortcode-button-purchase.php
+++ b/learnpress/inc/Shortcodes/class-lp-shortcode-button-purchase.php
@@ -1,84 +0,0 @@
-<?php
-/**
- * Button Purchase Shortcode.
- *
- * @author ThimPress
- * @category Shortcodes
- * @package Learnpress/Shortcodes
- * @version 3.0.1
- * @extends LP_Abstract_Shortcode
- */
-
-/**
- * Prevent loading this file directly
- */
-defined( 'ABSPATH' ) || exit();
-
-if ( ! class_exists( 'LP_Shortcode_Button_Purchase' ) ) {
-
- /**
- * Class LP_Shortcode_Button_Purchase
- *
- * @since 3.0.0
- */
- class LP_Shortcode_Button_Purchase extends LP_Abstract_Shortcode {
- /**
- * LP_Shortcode_Button_Purchase constructor.
- *
- * @param mixed $atts
- */
- public function __construct( $atts = '' ) {
- parent::__construct( $atts );
-
- $this->_atts = shortcode_atts(
- array(
- 'id' => 0,
- 'text' => '',
- ),
- $this->_atts
- );
- }
-
- /**
- * Output form.
- *
- * @return string
- */
- public function output() {
- ob_start();
-
- $atts = $this->_atts;
- if ( 'current' === $atts['id'] ) {
- $course_id = learn_press_is_course() ? get_the_ID() : 0;
- } else {
- $course_id = $atts['id'];
- }
-
- $course = learn_press_get_course( $course_id );
- if ( ! $course ) {
- return '';
- }
-
- if ( ! $course->is_free() ) {
- wp_enqueue_script( 'lp-single-course' );
- add_filter( 'learn-press/purchase-course-button-text', array( $this, 'button_text' ) );
- do_action( 'learn-press/course-buttons', $course );
- }
-
- return ob_get_clean();
- }
-
- /**
- * @param string $text
- *
- * @return string
- */
- public function button_text( $text ) {
- if ( $this->_atts['text'] ) {
- $text = $this->_atts['text'];
- }
-
- return $text;
- }
- }
-}
--- a/learnpress/inc/TemplateHooks/Admin/AdminListStudentsEnrolled.php
+++ b/learnpress/inc/TemplateHooks/Admin/AdminListStudentsEnrolled.php
@@ -55,7 +55,7 @@
$instructor_id = self::resolve_instructor_id_for_request( array() );
echo '<div class="wrap" id="lp-enrolled-students">';
- echo '<h1 class="wp-heading-inline">' . esc_html__( 'Enrolled Students', 'learnpress' ) . '</h1>';
+ echo '<h1 class="wp-heading-inline">' . esc_html__( 'Students', 'learnpress' ) . '</h1>';
do_action( 'learn-press/admin/enrolled-students/layout', $instructor_id );
echo '</div>';
}
--- a/learnpress/inc/TemplateHooks/Course/FilterCourseTemplate.php
+++ b/learnpress/inc/TemplateHooks/Course/FilterCourseTemplate.php
@@ -95,7 +95,10 @@
$wrapper = apply_filters(
'lp/filter-courses/sections/wrapper',
[
- 'wrapper' => sprintf( '<form class="%s">', $class_wrapper_form ),
+ 'wrapper' => sprintf(
+ '<form class="%s">',
+ esc_attr( $class_wrapper_form )
+ ),
'sections' => Template::combine_components( $sections ),
'close' => sprintf(
'<div class="lp-form-course-filter__close">%s<i class="lp-icon-close"></i></div>',
@@ -108,7 +111,7 @@
echo Template::combine_components( $wrapper );
} catch ( Throwable $e ) {
- error_log( __METHOD__ . ': ' . $e->getMessage() );
+ LP_Debug::error_log( $e );
}
}
@@ -151,7 +154,7 @@
$content = Template::combine_components( $wrapper );
} catch ( Throwable $e ) {
- error_log( __METHOD__ . ': ' . $e->getMessage() );
+ LP_Debug::error_log( $e );
}
return $content;
@@ -203,7 +206,7 @@
$content = Template::combine_components( $wrapper );
} catch ( Throwable $e ) {
- error_log( __METHOD__ . ': ' . $e->getMessage() );
+ LP_Debug::error_log( $e );
}
return $content;
--- a/learnpress/inc/TemplateHooks/CourseBuilder/Dashboard/BuilderDashboardTemplate.php
+++ b/learnpress/inc/TemplateHooks/CourseBuilder/Dashboard/BuilderDashboardTemplate.php
@@ -524,7 +524,7 @@
esc_html__( 'Top Enrolled Courses', 'learnpress' ),
esc_html__( 'Total:', 'learnpress' ),
esc_html( number_format_i18n( $total_enrolled ) ),
- esc_html__( 'enrolled students', 'learnpress' ),
+ esc_html__( 'students', 'learnpress' ),
$items_html
);
}
--- a/learnpress/inc/TemplateHooks/CourseBuilder/Lesson/BuilderEditLessonTemplate.php
+++ b/learnpress/inc/TemplateHooks/CourseBuilder/Lesson/BuilderEditLessonTemplate.php
@@ -420,7 +420,7 @@
$edit = [
'wrapper' => '<div class="cb-lesson-edit-title">',
'label' => sprintf( '<label for="title" class="cb-lesson-edit-title__label">%s</label>', __( 'Title', 'learnpress' ) ),
- 'input' => sprintf( '<input type="text" name="lesson_title" size="30" value="%s" id="title" class="cb-lesson-edit-title__input">', $title ),
+ 'input' => sprintf( '<input type="text" name="lesson_title" size="30" value="%s" id="title" class="cb-lesson-edit-title__input">', esc_attr( $title ) ),
'wrapper_end' => '</div>',
];
--- a/learnpress/inc/TemplateHooks/CourseBuilder/Lesson/BuilderListLessonsTemplate.php
+++ b/learnpress/inc/TemplateHooks/CourseBuilder/Lesson/BuilderListLessonsTemplate.php
@@ -92,7 +92,7 @@
$search = [
'wrapper' => sprintf( '<form class="cb-search-form" method="get" action="%s">', $link_tab ),
'search_lesson' => '<button class="lp-button cb-search-btn" type="submit"> <i class="lp-icon-search"> </i></button>',
- 'input' => sprintf( '<input class="cb-input-search-lesson" type="search" placeholder="%s" name="c_search" value="%s">', __( 'Search', 'learnpress' ), $args['c_search'] ?? '' ),
+ 'input' => sprintf( '<input class="cb-input-search-lesson" type="search" placeholder="%s" name="c_search" value="%s">', __( 'Search', 'learnpress' ), esc_attr( $args['c_search'] ?? '' ) ),
'wrapper_end' => '</form>',
];
--- a/learnpress/inc/TemplateHooks/CourseBuilder/Question/BuilderEditQuestionTemplate.php
+++ b/learnpress/inc/TemplateHooks/CourseBuilder/Question/BuilderEditQuestionTemplate.php
@@ -382,7 +382,7 @@
$edit = [
'wrapper' => '<div class="cb-question-edit-title">',
'label' => sprintf( '<label for="title" class="cb-question-edit-title__label">%s</label>', __( 'Title', 'learnpress' ) ),
- 'input' => sprintf( '<input type="text" name="question_title" size="30" value="%s" id="title" class="cb-question-edit-title__input">', $title ),
+ 'input' => sprintf( '<input type="text" name="question_title" size="30" value="%s" id="title" class="cb-question-edit-title__input">', esc_attr( $title ) ),
'wrapper_end' => '</div>',
];
--- a/learnpress/inc/TemplateHooks/CourseBuilder/Question/BuilderListQuestionsTemplate.php
+++ b/learnpress/inc/TemplateHooks/CourseBuilder/Question/BuilderListQuestionsTemplate.php
@@ -74,7 +74,7 @@
$search = [
'wrapper' => sprintf( '<form class="cb-search-form" method="get" action="%s">', $link_tab ),
'search_question' => '<button class="lp-button cb-search-btn" type="submit"> <i class="lp-icon-search"> </i></button>',
- 'input' => sprintf( '<input class="cb-input-search-question" type="search" placeholder="%s" name="c_search" value="%s">', __( 'Search', 'learnpress' ), $args['c_search'] ?? '' ),
+ 'input' => sprintf( '<input class="cb-input-search-question" type="search" placeholder="%s" name="c_search" value="%s">', __( 'Search', 'learnpress' ), esc_attr( $args['c_search'] ?? '' ) ),
'wrapper_end' => '</form>',
];
--- a/learnpress/inc/TemplateHooks/CourseBuilder/Quiz/BuilderEditQuizTemplate.php
+++ b/learnpress/inc/TemplateHooks/CourseBuilder/Quiz/BuilderEditQuizTemplate.php
@@ -426,7 +426,7 @@
$edit = [
'wrapper' => '<div class="cb-quiz-edit-title">',
'label' => sprintf( '<label for="title" class="cb-quiz-edit-title__label">%s</label>', __( 'Title', 'learnpress' ) ),
- 'input' => sprintf( '<input type="text" name="quiz_title" size="30" value="%s" id="title" class="cb-quiz-edit-title__input">', $title ),
+ 'input' => sprintf( '<input type="text" name="quiz_title" size="30" value="%s" id="title" class="cb-quiz-edit-title__input">', esc_attr( $title ) ),
'wrapper_end' => '</div>',
];
--- a/learnpress/inc/TemplateHooks/CourseBuilder/Quiz/BuilderListQuizzesTemplate.php
+++ b/learnpress/inc/TemplateHooks/CourseBuilder/Quiz/BuilderListQuizzesTemplate.php
@@ -72,7 +72,7 @@
$search = [
'wrapper' => sprintf( '<form class="cb-search-form" method="get" action="%s">', $link_tab ),
'search_quiz' => '<button class="lp-button cb-search-btn" type="submit"> <i class="lp-icon-search"> </i></button>',
- 'input' => sprintf( '<input class="cb-input-search-quiz" type="search" placeholder="%s" name="c_search" value="%s">', __( 'Search', 'learnpress' ), $args['c_search'] ?? '' ),
+ 'input' => sprintf( '<input class="cb-input-search-quiz" type="search" placeholder="%s" name="c_search" value="%s">', __( 'Search', 'learnpress' ), esc_attr( $args['c_search'] ?? '' ) ),
'wrapper_end' => '</form>',
];
--- a/learnpress/inc/admin/class-lp-install-sample-data.php
+++ b/learnpress/inc/admin/class-lp-install-sample-data.php
@@ -2,6 +2,7 @@
use LearnPressModelsCourseModel;
use LearnPressModelsCoursePostModel;
+use LearnPressServicesCourseService;
/**
* Class LP_Install_Sample_Data
@@ -16,22 +17,22 @@
/**
* @var array
*/
- public static $section_range = array( 5, 10 );
+ public static $section_range = array( 3, 3 );
/**
* @var array
*/
- public static $item_range = array( 10, 15 );
+ public static $item_range = array( 5, 10 );
/**
* @var array
*/
- public static $question_range = array( 10, 15 );
+ public static $question_range = array( 2, 5 );
/**
* @var array
*/
- public static $answer_range = array( 3, 5 );
+ public static $answer_range = array( 2, 5 );
/**
* @var int
@@ -122,16 +123,12 @@
self::$answer_range = $answer_range;
}
- $data['price'] = LP_Request::get_param( 'course-price', 0, 'float' );
+ $data['price'] = LP_Request::get_param( CoursePostModel::META_KEY_REGULAR_PRICE, 0, 'float' );
$data['name'] = LP_Request::get_param( 'custom-name' );
try {
$course_id = $this->create_course( $data );
- if ( ! $course_id ) {
- throw new Exception( 'Create course failed.' );
- }
-
$this->create_sections( $course_id );
$courseModel = CourseModel::find( $course_id, true );
@@ -342,9 +339,10 @@
*
* @param array $data
*
- * @return int|WP_Error
+ * @return int
+ * @throws Exception
*/
- protected function create_course( array $data ) {
+ protected function create_course( array $data ): int {
$title = $data['name'] ?? '';
$data_insert = array(
@@ -354,45 +352,56 @@
'post_content' => $this->generate_content( 25, 40, 5 ),
);
- $course_id = wp_insert_post( $data_insert );
+ $courseService = CourseService::instance();
+ $coursePostModel = $courseService->create_info_main( $data_insert );
- if ( $course_id ) {
- $metas = [
- CoursePostModel::META_KEY_DURATION => '10 week',
- CoursePostModel::META_KEY_SAMPLE_DATA => 'yes',
- CoursePostModel::META_KEY_LEVEL => 'all',
- ];
- foreach ( $metas as $key => $value ) {
- update_post_meta( $course_id, $key, $value );
- }
+ $course_id = $coursePostModel->get_id();
- $this->add_extra_info( $course_id );
+ // Set price
+ if ( $data['price'] > 0 ) {
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_PRICE} = $data['price'];
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_REGULAR_PRICE} = $data['price'];
}
- return $course_id;
- }
+ // Save meta data
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_DURATION} = '10 week';
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_SAMPLE_DATA} = 'yes';
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_LEVEL} = 'all';
- protected function add_extra_info( $course_id ) {
- $features = array( 'requirements', 'target_audiences', 'key_features' );
+ // Requirements
+ $requirements = array();
+ for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
+ $requirements[] = $this->generate_title();
+ }
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_REQUIREMENTS} = $requirements;
- // Requirements, Target audiences, Key Features
- foreach ( $features as $feature ) {
- $feature_data = array();
- for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
- $feature_data[] = $this->generate_title();
- }
- update_post_meta( $course_id, '_lp_' . $feature, $feature_data );
+ // Target audiences
+ $target_audiences = array();
+ for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
+ $target_audiences[] = $this->generate_title();
+ }
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_TARGET} = $target_audiences;
+
+ // Key features
+ $key_features = array();
+ for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
+ $key_features[] = $this->generate_title();
}
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_FEATURES} = $key_features;
// FAQs
- $feature_data = array();
+ $faqs = array();
for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
- $feature_data[] = array( $this->generate_title() . '?', $this->generate_content( 20, 30, 3 ) );
+ $faqs[] = array( $this->generate_title() . '?', $this->generate_content( 20, 30, 3 ) );
}
- update_post_meta( $course_id, '_lp_faqs', $feature_data );
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_FAQS} = $faqs;
// Featured review
- update_post_meta( $course_id, '_lp_featured_review', $this->generate_title( 30, 40 ) );
+ $coursePostModel->meta_data->{CoursePostModel::META_KEY_FEATURED_REVIEW} = $this->generate_title( 30, 40 );
+
+ $coursePostModel->save();
+
+ return $course_id;
}
/**
--- a/learnpress/inc/admin/sub-menus/class-lp-submenu-students-enrolled.php
+++ b/learnpress/inc/admin/sub-menus/class-lp-submenu-students-enrolled.php
@@ -11,8 +11,8 @@
*/
public function __construct() {
$this->id = 'learn-press-students-enrolled';
- $this->menu_title = __( 'Enrolled Students', 'learnpress' );
- $this->page_title = __( 'Enrolled Students', 'learnpress' );
+ $this->menu_title = __( 'Students', 'learnpress' );
+ $this->page_title = __( 'Students', 'learnpress' );
$this->priority = 20;
$this->callback = [ AdminListStudentsEnrolled::instance(), 'admin_page_output' ];
--- a/learnpress/inc/admin/views/meta-boxes/order/list-course-out-stock.php
+++ b/learnpress/inc/admin/views/meta-boxes/order/list-course-out-stock.php
@@ -1,29 +0,0 @@
-<?php
-if ( empty( $items_out_stock ) ) {
- return;
-}
-use LearnPressModelsCourseModel;
-
-$course_ids = explode( ',', $items_out_stock );
-?>
-<div class="lp-course-sold-out">
- <p class="lp-course-sold-out__title" style="font-style: italic; font-weight:bolder; color: darkred; font-size: 1rem;">
- <?php esc_html_e( 'List course out stock in order', 'learnpress' ); ?>
- </p>
- <ul class="lp-course-sold-out__list">
- <?php foreach ( $course_ids as $course_id ) : ?>
- <?php
- $course = CourseModel::find( $course_id );
- if ( empty( $course ) ) {
- continue;
- }
- ?>
-
- <li class="lp-course-sold-out__item">
- <a href="<?php echo esc_url_raw( $course->get_permalink() ); ?>">
- <?php echo wp_kses_post( $course->post_title ); ?>
- </a>
- </li>
- <?php endforeach; ?>
- </ul>
-</div>
--- a/learnpress/inc/admin/views/setup/steps/finish.php
+++ b/learnpress/inc/admin/views/setup/steps/finish.php
@@ -4,7 +4,7 @@
*
* @author ThimPres
* @package LearnPress/Admin/Views
- * @version 3.0.0
+ * @version 3.0.1
*/
defined( 'ABSPATH' ) or exit;
@@ -17,7 +17,7 @@
<a class="button"
id="install-sample-course"
href="<?php echo esc_url_raw( admin_url( 'admin.php?page=learn-press-tools' ) ); ?>">
- <?php _e( 'Install a demo course', 'learnpress' ); ?>
+ <?php _e( 'Install a Demo Course', 'learnpress' ); ?>
</a>
<a class="button" href="<?php echo LearnPress::$doc_link; ?>">
@@ -25,7 +25,7 @@
</a>
<a class="button" href="<?php echo esc_url_raw( admin_url( 'post-new.php?post_type=lp_course' ) ); ?>">
- <?php _e( 'Create a new course', 'learnpress' ); ?>
+ <?php _e( 'Create a New Course', 'learnpress' ); ?>
</a>
<a class="button" href="<?php echo esc_url_raw( admin_url( 'index.php' ) ); ?>">
--- a/learnpress/inc/admin/views/tools/course/html-install-sample-data.php
+++ b/learnpress/inc/admin/views/tools/course/html-install-sample-data.php
@@ -2,17 +2,12 @@
/**
* @author ThimPress
* @package LearnPress/Admin/Views
- * @version 3.0.0
+ * @version 3.0.1
*/
use LearnPressModelsCoursePostModel;
-defined( 'ABSPATH' ) or die();
-
-$section_range = LP_Install_Sample_Data::$section_range;
-$item_range = LP_Install_Sample_Data::$item_range;
-$question_range = LP_Install_Sample_Data::$question_range;
-$answer_range = LP_Install_Sample_Data::$answer_range;
+defined( 'ABSPATH' ) || die();
?>
<div class="lp-install-sample">
@@ -28,28 +23,27 @@
</li>
<li>
<p><?php _e( 'Random number of sections in range', 'learnpress' ); ?></p>
- <input type="number" size="3" value="<?php echo esc_attr( $section_range[0] ); ?>" min="1" max="20" name="section-range[]">
- <input type="number" size="3" value="<?php echo esc_attr( $section_range[1] ); ?>" min="1" max="20" name="section-range[]">
+ <input type="number" size="3" value="1" min="1" max="20" name="section-range[]">
+ <input type="number" size="3" value="3" min="1" max="20" name="section-range[]">
</li>
<li>
<p><?php _e( 'Random number of items in range (each section)', 'learnpress' ); ?></p>
- <input type="number" size="3" value="<?php echo esc_attr( $item_range[0] ); ?>" min="1" max="50" name="item-range[]">
- <input type="number" size="3" value="<?php echo esc_attr( $item_range[1] ); ?>" min="1" max="50" name="item-range[]">
+ <input type="number" size="3" value="1" min="1" max="50" name="item-range[]">
+ <input type="number" size="3" value="10" min="1" max="50" name="item-range[]">
</li>
<li>
<p><?php _e( 'Random number of questions in range (each quiz)', 'learnpress' ); ?></p>
- <input type="number" size="3" value="<?php echo esc_attr( $question_range[0] ); ?>" min="1" max="50" name="question-range[]">
- <input type="number" size="3" value="<?php echo esc_attr( $question_range[1] ); ?>" min="1" max="50" name="question-range[]">
+ <input type="number" size="3" value="1" min="1" max="50" name="question-range[]">
+ <input type="number" size="3" value="5" min="1" max="50" name="question-range[]">
</li>
<li>
<p><?php _e( 'Random number of answers in range (each question)', 'learnpress' ); ?></p>
- <input type="number" size="3" value="<?php echo esc_attr( $answer_range[0] ); ?>" min="1" max="10" name="answer-range[]">
- <input type="number" size="3" value="<?php echo esc_attr( $answer_range[1] ); ?>" min="1" max="10" name="answer-range[]">
+ <input type="number" size="3" value="2" min="1" max="10" name="answer-range[]">
+ <input type="number" size="3" value="5" min="1" max="10" name="answer-range[]">
</li>
<li>
<p><?php _e( 'Course price', 'learnpress' ); ?></p>
<input type="number" size="3" value="" min="0" name="<?php echo CoursePostModel::META_KEY_REGULAR_PRICE; ?>">
- <input type="hidden" value="all" name="<?php echo CoursePostModel::META_KEY_LEVEL; ?>">
</li>
</ul>
</fieldset>
--- a/learnpress/inc/background-process/class-lp-background-single-order.php
+++ b/learnpress/inc/background-process/class-lp-background-single-order.php
@@ -1,53 +0,0 @@
-<?php
-/**
- * Class LP_Background_Single_Course
- *
- * Single to run not schedule, run one time and done when be call
- *
- * @since 4.1.4
- * @author tungnx
- * @version 1.0.0
- */
-defined( 'ABSPATH' ) || exit;
-
-if ( ! class_exists( 'LP_Background_Order' ) ) {
- class LP_Background_Single_Order extends LP_Async_Request {
- protected $action = 'background_single_order';
- protected static $instance;
-
- /**
- * @var $lp_order LP_Order
- */
- protected $lp_order;
-
- /**
- * Get params via $_POST and handle
- */
- protected function handle() {
-
- }
-
- /**
- * Save course post data
- *
- * @throws Exception
- */
- protected function save_post() {
-
- }
-
- /**
- * @return LP_Background_Single_Order
- */
- public static function instance(): self {
- if ( is_null( self::$instance ) ) {
- self::$instance = new self();
- }
-
- return self::$instance;
- }
- }
-
- // Must run instance to register ajax.
- LP_Background_Single_Order::instance();
-}
--- a/learnpress/inc/background-process/class-lp-background-thim-cache.php
+++ b/learnpress/inc/background-process/class-lp-background-thim-cache.php
@@ -1,46 +0,0 @@
-<?php
-/**
- * Class LP_Background_Single_Course
- *
- * Single to run not schedule, run one time and done when be call
- *
- * @since 4.1.4
- * @author tungnx
- * @version 1.0.0
- */
-defined( 'ABSPATH' ) || exit;
-
-if ( ! class_exists( 'LP_Background_Thim_Cache' ) ) {
- class LP_Background_Thim_Cache extends LP_Async_Request {
- protected $action = 'background_thim_cache';
- protected static $instance;
-
- /**
- * Get params via $_POST and handle
- */
- protected function handle() {
- $key = LP_Helper::sanitize_params_submitted( $_POST['key'] ?? '' );
- $data = LP_Helper::sanitize_params_submitted( $_POST['data'] ?? '' );
- if ( empty( $key ) ) {
- return;
- }
-
- Thim_Cache_DB::instance()->set_value( $key, wp_unslash( $data ) );
- die();
- }
-
- /**
- * @return LP_Background_Thim_Cache
- */
- public static function instance(): self {
- if ( is_null( self::$instance ) ) {
- self::$instance = new self();
- }
-
- return self::$instance;
- }
- }
-
- // Must run instance to register ajax.
- LP_Background_Thim_Cache::instance();
-}
--- a/learnpress/inc/block-template/class-abstract-block-template.php
+++ b/learnpress/inc/block-template/class-abstract-block-template.php
@@ -1,78 +0,0 @@
-<?php
-
-use LearnPressHelpersTemplate;
-
-/**
- * Abstract_Block_Template class.
- *
- */
-abstract class Abstract_Block_Template extends WP_Block_Template {
- public $theme = 'learnpress/learnpress';
- public $type = 'wp_template';
- /**
- * @var string name of the block
- */
- public $name = '';
- public $origin = 'plugin';
- public $source = 'plugin'; // plugin|custom|theme, if custom save on db will be use 'custom'.
- public $content = ''; // Set content will be show on edit block and the frontend.
- public $has_theme_file = true;
- public $is_custom = false;
- public $path_html_block_template_file = '';
- public $path_template_render_default = '';
- /**
- * @var string path of the file run js.
- */
- public $source_js = '';
- /**
- * @var bool|string path of the file block.json metadata.
- */
- public $inner_block = false;
-
- public function __construct() {
- if ( ! wp_is_block_theme() ) {
- return;
- }
- $this->id = $this->theme . '//' . $this->slug;
- $template_file = '';
-
- if ( ! empty( $this->path_html_block_template_file ) ) {
- $template_file = Template::instance( false )->get_frontend_template_type_block(
- $this->path_html_block_template_file
- );
- }
-
- // Set content from theme file.
- if ( file_exists( $template_file ) ) {
- $content = file_get_contents( $template_file );
- if ( version_compare( get_bloginfo( 'version' ), '6.4-beta', '>=' ) ) {
- $this->content = traverse_and_serialize_blocks( parse_blocks( $content ) );
- } else {
- $this->content = _inject_theme_attribute_in_block_template_content( $content );
- }
- }
- }
-
- /**
- * Render content of block tag
- *
- * @param array $attributes | Attributes of block tag.
- *
- * @return false|string
- */
- public function render_content_block_template( array $attributes ) {
- $content = '';
-
- try {
- ob_start();
- $template = $this->path_template_render_default;
- Template::instance()->get_frontend_template( $template, compact( 'attributes' ) );
-
- $content = ob_get_clean();
- } catch ( Throwable $e ) {
- ob_end_clean();
- }
-
- return $content;
- }
-}
--- a/learnpress/inc/block-template/class-block-template-archive-course.php
+++ b/learnpress/inc/block-template/class-block-template-archive-course.php
@@ -1,20 +0,0 @@
-<?php
-
-/**
- * Class Block_Template_Archive_Course
- *
- * Handle register, render block template
- */
-class Block_Template_Archive_Course extends Abstract_Block_Template {
- public $slug = 'archive-lp_course';
- public $name = 'learnpress/archive-course';
- public $title = 'Course Archive (LearnPress)';
- public $description = 'Course Archive Block Template';
- public $path_html_block_template_file = 'html/archive-lp_course.html';
- public $path_template_render_default = 'archive-course.php';
- public $source_js = LP_PLUGIN_URL . 'assets/js/dist/blocks/archive-course.js';
-
- public function __construct() {
- parent::__construct();
- }
-}
--- a/learnpress/inc/block-template/class-block-template-handle.php
+++ b/learnpress/inc/block-template/class-block-template-handle.php
@@ -1,191 +0,0 @@
-<?php
-
-use LearnPressHelpersConfig;
-
-/**
- * Class Block_Template_Handle
- *
- * Handle register, render block template
- */
-class Block_Template_Handle {
- public static function instance() {
- static $instance = null;
-
- if ( is_null( $instance ) ) {
- $instance = new self();
- }
-
- return $instance;
- }
-
- /**
- * Hooks handle block template
- */
- protected function __construct() {
- add_filter( 'get_block_templates', array( $this, 'add_block_templates' ), 10, 3 );
- add_filter( 'pre_get_block_file_template', array( $this, 'edit_block_file_template' ), 10, 3 );
- add_action( 'init', array( $this, 'register_tag_block' ) );
- // Register block category
- add_filter( 'block_categories_all', array( $this, 'add_block_category' ), 10, 2 );
- }
-
- /**
- * Register block, render content of block
- *
- * @return void
- */
- public function register_tag_block() {
- $block_templates = Config::instance()->get( 'block-templates' );
-
- /**
- * @var Abstract_Block_Template $block_template
- */
- foreach ( $block_templates as $block_template ) {
- // Register script.
- wp_register_script(
- $block_template->name, // Block name
- $block_template->source_js, // Block script
- array( 'wp-blocks' ), // Dependencies
- uniqid() // Version
- );
-
- // Render content block template child of parent block
- if ( $block_template->inner_block ) {
- /**
- * @see Block_Title_Course::render_content_inner_block_template
- */
- register_block_type_from_metadata(
- $block_template->inner_block,
- [
- 'render_callback' => [ $block_template, 'render_content_inner_block_template' ],
- ]
- );
- continue;
- }
-
- // Render content block template parent
- register_block_type(
- $block_template->name,
- [
- 'render_callback' => [ $block_template, 'render_content_block_template' ],
- 'editor_script' => $block_template->name,
- ]
- );
- }
- }
-
- /**
- * Add blocks template
- *
- * @param array $query_result Array of template objects.
- * @param array $query Optional. Arguments to retrieve templates.
- * @param mixed $template_type wp_template or wp_template_part.
- *
- * @return array
- */
- public function add_block_templates( array $query_result, array $query, $template_type ): array {
- if ( $template_type === 'wp_template_part' ) { // Template not Template part
- return $query_result;
- }
-
- $lp_block_templates = Config::instance()->get( 'block-templates' );
-
- foreach ( $lp_block_templates as $block_template ) {
- $new = new $block_template();
-
- // Get block template if custom - save on table posts.
- $block_custom = $this->is_custom_block_template( $template_type, $new->slug );
- if ( $block_custom ) {
- $new->is_custom = true;
- $new->source = 'custom';
- if ( version_compare( get_bloginfo( 'version' ), '6.4-beta', '>=' ) ) {
- $new->content = traverse_and_serialize_blocks( parse_blocks( $block_custom->post_content ) );
- } else {
- $new->content = _inject_theme_attribute_in_block_template_content( $block_custom->post_content );
- }
- }
-
- if ( empty( $query ) ) { // For Admin and rest api call to this function, so $query is empty
- $query_result[] = $new;
- } else {
- $slugs = $query['slug__in'] ?? array();
- if ( in_array( $new->slug, $slugs ) ) {
- $query_result[] = $new;
- }
- }
- }
-
- return $query_result;
- }
-
- /**
- * Load template block when edit and save.
- *
- * @param WP_Block_Template|null $template
- * @param string $id
- * @param $template_type
- *
- * @return WP_Block_Template|null
- */
- public function edit_block_file_template( WP_Block_Template $template = null, string $id, $template_type ) {
- $lp_block_templates = Config::instance()->get( 'block-templates' );
-
- foreach ( $lp_block_templates as $block_template ) {
- if ( $id === $block_template->id ) {
- $template = $block_template;
- break;
- }
- }
-
- return $template;
- }
-
- /**
- * Check is custom block template
- *
- * @param $template_type
- * @param $post_name
- *
- * @return WP_Post|null
- */
- public function is_custom_block_template( $template_type, $post_name ) {
- $post_block_theme = null;
-
- $check_query_args = array(
- 'post_type' => $template_type,
- 'posts_per_page' => 1,
- 'no_found_rows' => true,
- 'post_name__in' => array( $post_name ),
- );
-
- $check = new WP_Query( $check_query_args );
-
- if ( count( $check->get_posts() ) > 0 ) {
- $post_block_theme = $check->get_posts()[0];
- }
-
- return $post_block_theme;
- }
-
- /**
- * Register block category
- *
- * @param array $block_categories
- * @param $editor_context
- *
- * @return array
- */
- public function add_block_category( array $block_categories, $editor_context ) {
- $lp_category_block = array(
- 'slug' => 'learnpress-category',
- 'title' => __( 'LearnPress Category', 'learnpress' ),
- 'icon' => null,
- );
-
- array_unshift( $block_categories, $lp_category_block );
-
- return $block_categories;
- }
-}
-
-Block_Template_Handle::instance();
--- a/learnpress/inc/block-template/class-block-template-item-curriculum-course.php
+++ b/learnpress/inc/block-template/class-block-template-item-curriculum-course.php
@@ -1,20 +0,0 @@
-<?php
-
-/**
- * Class Block_Template_Single_Course
- *
- * Handle register, render block template
- */
-class Block_Template_Item_Curriculum_Course extends Abstract_Block_Template {
- public $slug = 'item-curriculum-course';
- public $name = 'learnpress/item-curriculum-course';
- public $title = 'Item curriculum Course (LearnPress)';
- public $description = 'Item Curriculum Course Block Template';
- public $path_html_block_template_file = 'html/item-curriculum-course.html';
- public $path_template_render_default = 'content-single-item.php';
- public $source_js = LP_PLUGIN_URL . 'assets/js/dist/blocks/item-curriculum-course.js';
-
- public function __construct() {
- parent::__construct();
- }
-}
--- a/learnpress/inc/block-template/class-block-template-single-course.php
+++ b/learnpress/inc/block-template/class-block-template-single-course.php
@@ -1,49 +0,0 @@
-<?php
-
-use LearnPressModelsCourseModel;
-
-/**
- * Class Block_Template_Single_Course
- *
- * Handle register, render block template
- */
-class Block_Template_Single_Course extends Abstract_Block_Template {
- public $slug = 'single-lp_course';
- public $name = 'learnpress/single-course';
- public $title = 'Single Course (LearnPress)';
- public $description = 'Single Course Block Template';
- public $path_html_block_template_file = 'html/single-lp_course.html';
- public $path_template_render_default = 'single-course.php';
- public $source_js = LP_PLUGIN_URL . 'assets/js/dist/blocks/single-course.js';
-
- public function __construct() {
- parent::__construct();
- }
-
- /**
- * Render content of block tag
- *
- * @param array $attributes | Attributes of block tag.
- *
- * @return false|string
- */
- public function render_content_block_template( array $attributes ) {
- global $wp;
- $object = get_queried_object();
- $vars = $wp->query_vars;
- // Todo: For item course current display on post_type course
- // After when handle display item course on correct post_type item, remove this code.
- if ( ! empty( $vars['course-item'] ) ) {
- global $post;
- setup_postdata( $post );
- $this->path_template_render_default = 'content-single-item.php';
- } elseif ( $object ) {
- $course = CourseModel::find( $object->ID, true );
- if ( $course && $course->is_offline() ) {
- $this->path_template_render_default = 'single-course-offline.php';
- }
- }
-
- return parent::render_content_block_template( $attributes );
- }
-}
--- a/learnpress/inc/class-lp-multi-language.php
+++ b/learnpress/inc/class-lp-multi-language.php
@@ -1,70 +0,0 @@
-<?php
-defined( 'ABSPATH' ) || exit;
-
-if ( ! class_exists( 'LP_Multi_Language' ) ) {
- /**
- * Class LP_Multi_Language
- *
- * @author ThimPress
- * @package LearnPress/Clases
- * @version 1.0
- */
- class LP_Multi_Language {
- public static function init() {
- self::load_plugin_text_domain( LP_PLUGIN_FILE );
- }
-
- /**
- * Helper function to load text-domain for LP addons.
- *
- * @param string $path
- * @param string $text_domain
- * @param string $language_folder
- */
- public static function load_plugin_text_domain( $path, $text_domain = '', $language_folder = 'languages' ) {
- // Get absolute plugin folder instead of plugin file
- if ( false !== strpos( $path, '.php' ) ) {
- $path = dirname( $path );
- }
-
- // Plugin folder, such as: learnpress-offline-payment
- $plugin_folder = basename( $path );
-
- // If name of text-domain is not set
- if ( ! $text_domain ) {
- $text_domain = $plugin_folder;
- }
-
- $locale = apply_filters( 'plugin_locale', get_locale(), $text_domain );
-
- if ( is_admin() ) {
- load_textdomain( $text_domain, WP_LANG_DIR . "/{$plugin_folder}/{$plugin_folder}-admin-{$locale}.mo" );
- load_textdomain( $text_domain, WP_LANG_DIR . "/plugins/{$plugin_folder}-admin-{$locale}.mo" );
- }
-
- load_textdomain( $text_domain, WP_LANG_DIR . "/{$plugin_folder}/{$plugin_folder}-{$locale}.mo" );
-
- $mo = WP_CONTENT_DIR . "/plugins/{$plugin_folder}/languages/{$plugin_folder}-{$locale}.mo";
- load_textdomain( $text_domain, $mo );
- load_plugin_textdomain( $text_domain, false, plugin_basename( $path ) . '/' . $language_folder );
-
- }
- }
-}
-
-LP_Multi_Language::init();
-
-if ( ! function_exists( 'learn_press_load_plugin_text_domain' ) ) {
- /**
- * Load plugin text domain
- *
- * @param string $path - Path to plugin
- * @param string $text_domain - Name of text-domain
- * @param string $language_folder - Folder inside the plugin that contains language files
- */
- function learn_press_load_plugin_text_domain( $path, $text_domain = '', $language_folder = '' ) {
-
- LP_Multi_Language::load_plugin_text_domain( $path, $text_domain, $language_folder );
-
- }
-}
--- a/learnpress/inc/class-lp-nonce-helper.php
+++ b/learnpress/inc/class-lp-nonce-helper.php
@@ -1,88 +0,0 @@
-<?php
-
-/**
- * Class LP_Nonce_Helper
- */
-class LP_Nonce_Helper {
- /**
- * Create nonce for course action.
- * Return nonce created with format 'learn-press-$action-$course_id-course-$user_id'
- *
- * @param string $action [retake, purchase, enroll]
- * @param int $course_id
- * @param int $user_id
- *
- * @since 3.0.0
- *
- * @return string
- */
- public static function create_course( $action, $course_id = 0, $user_id = 0 ) {
- if ( ! $course_id ) {
- $course_id = get_the_ID();
- }
-
- if ( ! $user_id ) {
- $user_id = get_current_user_id();
- }
-
- return wp_create_nonce( sprintf( 'learn-press-%s-course-%s-%s', $action, $course_id, $user_id ) );
- }
-
- /**
- * Verify nonce for course action.
- *
- * @param string $nonce
- * @param string $action
- * @param int $course_id
- * @param int $user_id
- *
- * @since 3.0.0
- *
- * @return bool
- * @deprecated 4.1.6.9
- */
- /*public static function verify_course( $nonce, $action, $course_id = 0, $user_id = 0 ) {
- if ( ! $course_id ) {
- $course_id = get_the_ID();
- }
-
- if ( ! $user_id ) {
- $user_id = get_current_user_id();
- }
-
- return wp_verify_nonce( $nonce, sprintf( 'learn-press-%s-course-%s-%s', $action, $course_id, $user_id ) );
- }*/
-
- public static function quiz_action( $action, $quiz_id, $course_id, $ajax = false ) {
- ?>
- <input type="hidden" name="quiz-id" value="<?php echo esc_attr( $quiz_id ); ?>">
- <input type="hidden" name="course-id" value="<?php echo esc_attr( $course_id ); ?>">
- <?php if ( $ajax ) { ?>
- <input type="hidden" name="lp-ajax" value="<?php echo esc_attr( $action ); ?>-quiz">
- <?php } else { ?>
- <input type="hidden" name="lp-<?php echo esc_attr( $action ); ?>-quiz" value="<?php echo esc_attr( $quiz_id ); ?>">
- <?php } ?>
- <input type="hidden" name="<?php echo esc_attr( $action ); ?>-quiz-nonce" value="<?php echo wp_create_nonce( sprintf( 'learn-press/quiz/%s/%s-%s-%s', $action, get_current_user_id(), $course_id, $quiz_id ) ); ?>">
- <?php
- }
-
- /**
- * @deprecated 4.1.6.9
- */
- /*public static function verify_quiz_action( $action, $nonce = '', $quiz_id = 0, $course_id = 0 ) {
- if ( ! $nonce ) {
- $nonce = LP_Request::get_post( $action . '-quiz-nonce' );
- }
-
- if ( ! $quiz_id ) {
- global $lp_course_item;
- $quiz_id = $lp_course_item instanceof LP_Course_Item ? $lp_course_item->get_id() : 0;
- }
-
- if ( ! $course_id ) {
- $course_id = get_the_ID();
- }
-
- return wp_verify_nonce( $nonce, sprintf( 'learn-press/quiz/%s/%s-%s-%s', $action, get_current_user_id(), $course_id, $quiz_id ) );
- }*/
-}
--- a/learnpress/inc/gateways/class-lp-gateway-none.php
+++ b/learnpress/inc/gateways/class-lp-gateway-none.php
@@ -1,27 +0,0 @@
-<?php
-/**
- * Class LP_Gateway_None
- *
- * @author ThimPress
- * @package LearnPress/Classes
- * @version 1.0
- */
-
-if ( ! defined( 'ABSPATH' ) ) {
- exit;
-}
-
-class LP_Gateway_None extends LP_Gateway_Abstract {
- /**
- * @param $order_id
- *
- * @return mixed
- */
- public function process_payment( $order_id ) {
- $order = new LP_Order( $order_id );
-
- $order->payment_complete();
-
- return array( 'result' => 'success' );
- }
-}
--- a/learnpress/inc/gateways/paypal/class-lp-gateway-paypal.php
+++ b/learnpress/inc/gateways/paypal/class-lp-gateway-paypal.php
@@ -213,10 +213,10 @@
$paypal_payment_url = $this->create_payment_url( $order );
}
- $result['result'] = 'success';
- $result['redirect'] = $paypal_payment_url;
-
- return $result;
+ return [
+ 'result' => 'success',
+ 'redirect' => $paypal_payment_url,
+ ];
}
/**
--- a/learnpress/inc/lesson/lp-lesson-functions.php
+++ b/learnpress/inc/lesson/lp-lesson-functions.php
@@ -1,82 +0,0 @@
-<?php
-/**
- * Lession function.
- *
- * @author ThimPress
- * @version 4.0.0
- * @deprecated 4.2.2
- */
-
-defined( 'ABSPATH' ) || exit();
-
-function learn_press_lesson_comment_form_fields( $post_id ) {
- if ( empty( $_REQUEST['content-item-only'] ) ) {
- return;
- }
- ?>
-
- <input type="hidden" name="content-item-only-redirect" value="<?php echo learn_press_get_current_url(); ?>"/>
- <input type="hidden" name="content-item-only" value="yes"/>
-
- <?php
-}
-//add_action( 'comment_form', 'learn_press_lesson_comment_form_fields' );
-
-if ( ! function_exists( 'learn_press_get_only_content_permalink' ) ) {
- function learn_press_get_only_content_permalink( $redirect, $comment ) {
- if ( empty( $_REQUEST['content-item-only'] ) || sanitize_text_field( $_REQUEST['content-item-only'] ) !== 'yes' ) {
- return $redirect;
- }
-
- if ( empty( $_REQUEST['content-item-only-redirect'] ) ) {
- return $redirect;
- }
-
- if ( get_post_type( $comment->comment_post_ID ) != 'lp_lesson' ) {
- return $redirect;
- }
-
- return esc_url_raw( add_query_arg( 'content-item-only', 'yes', LP_Helper::sanitize_params_submitted( $_REQUEST['content-item-only-redirect'] ) ) );
- }
-}
-//add_filter( 'comment_post_redirect', 'learn_press_get_only_content_permalink', 10, 2 );
-
-/*function learn_press_lesson_comment_form() {
- global $post;
-
- $course = learn_press_get_course();
- if ( ! $course ) {
- return;
- }
-
- $lesson = LP_Global::course_item();
- if ( ! $lesson ) {
- return;
- }
-
- $user = learn_press_get_current_user();
-
- if ( $lesson->setup_postdata() ) {
- if ( comments_open() || get_comments_number() ) {
- add_filter( 'deprecated_file_trigger_error', '__return_false' );
- comments_template();
- remove_filter( 'deprecated_file_trigger_error', '__return_false' );
- }
-
- $lesson->reset_postdata();
- }
-
-}*/
-
-/**
- * Remove data section after remove lesson
- */
-function learn_press_lesson_before_delete_post( $post_id, $force = false ) {
- global $wpdb;
-
- if ( 'lp_lesson' === get_post_type( $post_id ) ) {
- $sql = 'DELETE FROM `' . $wpdb->prefix . 'learnpress_section_items` WHERE `item_id` = ' . $post_id . ' AND `item_type` = "lp_lesson"';
- $wpdb->query( $sql );
- }
-}
-//add_action( 'delete_post', 'learn_press_lesson_before_delete_post', 10, 2 );
--- a/learnpress/inc/order/lp-order-functions.php
+++ b/learnpress/inc/order/lp-order-functions.php
@@ -503,7 +503,7 @@
* Build normalized refund event payload.
*
* @since 4.3.5
- * @version 1.0.0
+ * @version 1.0.1
*
* @param LP_Order $order
* @param array $overrides
@@ -522,7 +522,7 @@
);
}
- $user_id = $order->get_user_id();
+ $user_id = (int) $order->get_user_id();
$userOrderModel = UserModel::find( $user_id, true );
if ( $userOrderModel instanceof UserModel ) {
$requested_by = $userOrderModel->get_display_name();
--- a/learnpress/inc/rest-api/v1/admin/class-lp-admin-rest-tools-controller.php
+++ b/learnpress/inc/rest-api/v1/admin/class-lp-admin-rest-tools-controller.php
@@ -677,9 +677,9 @@
*
* @return bool
*/
- public function check_permission(): bool {
+ public function check_permission( $request = null ): bool {
$permission = current_user_can( ADMIN_ROLE );
- $permission = apply_filters( 'learn-press/api-admin-tools/permission', $permission );
+ $permission = apply_filters( 'learn-press/api-admin-tools/permission', $permission, $request );
return $permission;
}
--- a/learnpress/inc/rest-api/v1/frontend/class-lp-rest-gateway-webhook-controller.php
+++ b/learnpress/inc/rest-api/v1/frontend/class-lp-rest-gateway-webhook-controller.php
@@ -53,13 +53,13 @@
*
* @return Response
* @since 4.3.7
- * @version 1.0.0
+ * @version 1.0.1
*/
public function listen_subscription_webhook( WP_REST_Request $request ): Response {
- $response = new Response();
+ $response = new Response();
+ $gateway_id = sanitize_key( (string) $request->get_param( 'gateway' ) );
try {
- $gateway_id = sanitize_key( (string) $request->get_param( 'gateway' ) );
if ( empty( $gateway_id ) ) {
throw new Exception( __( 'Gateway is required.', 'learnpress' ), 400 );
}
@@ -73,13 +73,14 @@
throw new Exception( __( 'Gateway is not enable.', 'learnpress' ), 404 );
}
- LP_Debug::log_to_comment( 'Webhook payload: ' . json_encode( $request->get_body(), JSON_UNESCAPED_UNICODE ) );
+ //LP_Debug::log_to_comment( 'Webhook payload: ' . json_encode( $request->get_body(), JSON_UNESCAPED_UNICODE ) );
/**
* @var LP_Gateway_Paypal|LP_Gateway_Stripe $gateway
*/
$gateway->capture_subscription_webhook( $request );
} catch ( Throwable $e ) {
+ LP_Debug::log_to_comment( 'Webhook error: ' . $gateway_id . ' - ' . $e->getMessage() );
LP_Debug::error_log( $e );
$response->message = $e->getMessage();
}
--- a/learnpress/inc/rest-api/v1/frontend/class-lp-rest-orders-controller.php
+++ b/learnpress/inc/rest-api/v1/frontend/class-lp-rest-orders-controller.php
@@ -1,58 +0,0 @@
-<?php
-
-use LearnPressHelpersTemplate;
-
-class LP_REST_Orders_Controller extends LP_Abstract_REST_Controller {
- public function __construct() {
- $this->namespace = 'lp/v1';
- $this->rest_base = 'orders';
-
- parent::__construct();
- }
-
- public function register_routes() {
- $this->routes = array(
- 'statistic' => array(
- array(
- 'methods' => WP_REST_Server::READABLE,
- 'callback' => array( $this, 'statistic' ),
- 'permission_callback' => '__return_true',
- ),
- ),
- );
-
- parent::register_routes();
- }
-
- /**
- * Get statistic of orders.
- *
- * @param WP_REST_Request $request
- *
- * @return LP_REST_Response
- * @since 4.0.0
- * @version 1.0.1
- */
- public function statistic( WP_REST_Request $request ): LP_REST_Response {
- $response = new LP_REST_Response();
- $response->data = '';
-
- try {
- //$order_statuses = learn_press_get_order_statuses( true, true );
- $order_statuses = LP_Order::get_order_statuses();
- $lp_order_icons = LP_Order::get_icons_status();
-
- ob_start();
- $data = compact( 'order_statuses', 'lp_order_icons' );
- Template::instance()->get_admin_template( 'dashboard/html-orders', $data );
- $response->data = ob_get_clean();
- $response->status = 'success';
- } catch ( Throwable $e ) {
- ob_end_clean();
- $response->message = $e->getMessage();
- }
-
- return $response;
- }
-
-}
--- a/learnpress/learnpress.php
+++ b/learnpress/learnpress.php
@@ -4,7 +4,7 @@
* Plugin URI: https://thimpress.com/learnpress
* Description: LearnPress is a WordPress complete solution for creating a Learning Management System (LMS). It can help you to create courses, lessons and quizzes.
* Author: ThimPress
- * Version: 4.4.0
+ * Version: 4.4.1
* Author URI: http://thimpress.com
* Requires at least: 6.0
* Requires PHP: 7.4
--- a/learnpress/templates/checkout/form.php
+++ b/learnpress/templates/checkout/form.php
@@ -6,7 +6,7 @@
*
* @author ThimPress
* @package Learnpress/Templates
- * @version 4.0.5
+ * @version 4.0.6
*/
defined( 'ABSPATH' ) || exit();
@@ -15,16 +15,22 @@
?>
<?php
if ( ! is_user_logged_in() ) {
+ $enable_login_on_page_checkout = LP_Settings::get_option( 'enable_login_checkout', 'yes' ) === 'yes';
+ $login_text = sprintf(
+ '<a class="lp-link-login" href="%s">%s</a>',
+ learn_press_get_login_url( LP_Helper::getUrlCurrent() ),
+ __( 'login', 'learnpress' )
+ );
+
+ if ( $enable_login_on_page_checkout ) {
+ $login_text = __( 'login', 'learnpress' );
+ }
?>
<div class="learn-press-message error">
<?php
printf(
__( 'Please %s in to enroll in the course!', 'learnpress' ),
- sprintf(
- '<a class="lp-link-login" href="%s">%s</a>',
- learn_press_get_login_url( LP_Helper::getUrlCurrent() ),
- __( 'login', 'learnpress' )
- )
+ $login_text
);
?>
</div>
--- a/learnpress/vendor/autoload.php
+++ b/learnpress/vendor/autoload.php
@@ -19,4 +19,4 @@
require_once __DIR__ . '/composer/autoload_real.php';
-return ComposerAutoloaderInit0f605074db146227d4f3cabab672b077::getLoader();
+return ComposerAutoloaderInitdbee25fcb9cbfa5a93c4beebb98321da::getLoader();
--- a/learnpress/vendor/composer/autoload_real.php
+++ b/learnpress/vendor/composer/autoload_real.php
@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
-class ComposerAutoloaderInit0f605074db146227d4f3cabab672b077
+class ComposerAutoloaderInitdbee25fcb9cbfa5a93c4beebb98321da
{
private static $loader;
@@ -22,12 +22,12 @@
return self::$loader;
}
- spl_autoload_register(array('ComposerAutoloaderInit0f605074db146227d4f3cabab672b077', 'loadClassLoader'), true, true);
+ spl_autoload_register(array('ComposerAutoloaderInitdbee25fcb9cbfa5a93c4beebb98321da', 'loadClassLoader'), true, true);
self::$loader = $loader = new ComposerAutoloadClassLoader(dirname(__DIR__));
- spl_autoload_unregister(array('ComposerAutoloaderInit0f605074db146227d4f3cabab672b077', 'loadClassLoader'));
+ spl_autoload_unregister(array('ComposerAutoloaderInitdbee25fcb9cbfa5a93c4beebb98321da', 'loadClassLoader'));
require __DIR__ . '/autoload_static.php';
- call_user_func(ComposerAutoloadComposerStaticInit0f605074db146227d4f3cabab672b077::getInitializer($loader));
+ call_user_func(ComposerAutoloadComposerStaticInitdbee25fcb9cbfa5a93c4beebb98321da::getInitializer($loader));
$loader->register(true);
--- a/learnpress/vendor/composer/autoload_static.php
+++ b/learnpress/vendor/composer/autoload_static.php
@@ -4,7 +4,7 @@
namespace ComposerAutoload;
-class ComposerStaticInit0f605074db146227d4f3cabab672b077
+class ComposerStaticInitdbee25fcb9cbfa5a93c4beebb98321da
{
public static $prefixLengthsPsr4 = array (
'T' =>
@@ -43,9 +43,9 @@
public static function getInitializer(ClassLoader $loader)
{
return Closure::bind(function () use ($loader) {
- $loader->prefixLengthsPsr4 = ComposerStaticInit0f605074db146227d4f3cabab672b077::$prefixLengthsPsr4;
- $loader->prefixDirsPsr4 = ComposerStaticInit0f605074db146227d4f3cabab672b077::$prefixDirsPsr4;
- $loader->classMap = ComposerStaticInit0f605074db146227d4f3cabab672b077::$classMap;
+ $loader->prefixLengthsPsr4 = ComposerStaticInitdbee25fcb9cbfa5a93c4beebb98321da::$prefixLengthsPsr4;
+ $loader->prefixDirsPsr4 = ComposerStaticInitdbee25fcb9cbfa5a93c4beebb98321da::$prefixDirsPsr4;
+ $loader->classMap = ComposerStaticInitdbee25fcb9cbfa5a93c4beebb98321da::$classMap;
}, null, ClassLoader::class);
}
--- a/learnpress/vendor/composer/installed.php
+++ b/learnpress/vendor/composer/installed.php
@@ -3,7 +3,7 @@
'name' => 'learnpress/learnpress',
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
- 'reference' => '398e577108f7adb5e7f883dfc48a912ae1e26624',
+ 'reference' => '67327f73fa28c0020691be8cdfb314c105bba708',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -13,16 +13,16 @@
'learnpress/learnpress' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
- 'reference' => '398e577108f7adb5e7f883dfc48a912ae1e26624',
+ 'reference' => '67327f73fa28c0020691be8cdfb314c105bba708',
'type' => 'library',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'dev_requirement' => false,
),
'symfony/css-selector' => array(
- 'pretty_version' => 'v6.4.34',
- 'version' => '6.4.34.0',
- 'reference' => 'b0314c186f1464de048cce58979ff1625ca88bbb',
+ 'pretty_version' => 'v8.1.0',
+ 'version' => '8.1.0.0',
+ 'reference' => 'dc0e2be45c9b5588c82414f02ac574b4b986abcd',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/css-selector',
'aliases' => array(),
--- a/learnpress/vendor/symfony/css-selector/Exception/SyntaxErrorException.php
+++ b/learnpress/vendor/symfony/css-selector/Exception/SyntaxErrorException.php
@@ -17,7 +17,7 @@
* ParseException is thrown when a CSS selector syntax is not valid.
*
* This component is a port of the Python cssselect library,
- * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect.
+ * which is copyright Ian Bicking, @see https://github.com/scrapy/cssselect.
*
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*/
@@ -40,7 +40,12 @@
public static function nestedNot(): self
{
- return new self('Got nested ::not().');
+ return new self('Got nested :not().');
+ }
+
+ public static function nestedHas(): self
+ {
+ return new self('Got too deeply nested :has().');
}
public static function notAtTheStartOfASelector(string $pseudoElement): self
--- a/learnpress/vendor/symfony/css-selector/Node/AttributeNode.php
+++ b/learnpress/vendor/symfony/css-selector/Node/AttributeNode.php
@@ -23,19 +23,13 @@
*/
class AttributeNode extends AbstractNode
{
- private NodeInterface $selector;
- private ?string $namespace;
- private string $attribute;
- private string $operator;
- private ?string $value;
-
- public function __construct(NodeInterface $selector, ?string $namespace, string $attribute, string $operator, ?string $value)
- {
- $this->selector = $selector;
- $this->namespace = $namespace;
- $this->attribute = $attribute;
- $this->operator = $operator;
- $this->value = $value;
+ public function __construct(
+ private NodeInterface $selector,
+ private ?string $namespace,
+ private string $attribute,
+ private string $operator,
+ private ?string $value,
+ ) {
}
public function getSelector(): NodeInterface
--- a/learnpress/vendor/symfony/css-selector/Node/ClassNode.php
+++ b/learnpress/vendor/symfony/css-selector/Node/ClassNode.php
@@ -23,13 +23,10 @@
*/
class ClassNode extends AbstractNode
{
- private NodeInterface $selector;
- private string $name;
-
- public function __construct(NodeInterface $selector, string $name)
- {
- $this->selector = $selector;
- $this->name = $name;
+ public function __construct(
+ private NodeInterface $selector,
+ private string $name,
+ ) {
}
public function getSelector(): NodeInterface
--- a/learnpress/vendor/symfony/css-selector/Node/CombinedSelectorNode.php
+++ b/learnpress/vendor/symfony/css-selector/Node/CombinedSelectorNode.php
@@ -23,15 +23,11 @@
*/
class CombinedSelectorNode extends AbstractNode
{
- private NodeInterface $selector;
- p