diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad51ab7b2c..3abded92e0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,23 @@
LifterLMS Changelog
===================
+v7.7.6 - 2024-08-22
+-------------------
+
+##### Bug Fixes
+
++ Avoid modifying the Lost Password link if no LifterLMS Dashboard page is set. [#2741](https://github.com/gocodebox/lifterlms/issues/2741)
++ Fixes placeholder label on the Dashboard Page selection dropdown. [#2708](https://github.com/gocodebox/lifterlms/issues/2708)
++ Avoid outputting lifterlms_membership_link content if the membership is not published. [#2724](https://github.com/gocodebox/lifterlms/issues/2724)
++ Fix display of quiz question when viewing the quiz results if it contains formatting. [#2734](https://github.com/gocodebox/lifterlms/issues/2734)
++ Fixes sanitization as reported by FKSEC.
++ Fixes warning when trying to get the contents of a media protection file that does not exist. [#2735](https://github.com/gocodebox/lifterlms/issues/2735)
+
+##### Updated Templates
+
++ [templates/quiz/results-attempt-questions-list.php](https://github.com/gocodebox/lifterlms/blob/7.7.6/templates/quiz/results-attempt-questions-list.php)
+
+
v7.7.5 - 2024-08-15
-------------------
diff --git a/class-lifterlms.php b/class-lifterlms.php
index c670a2608d..3dd32874d5 100644
--- a/class-lifterlms.php
+++ b/class-lifterlms.php
@@ -34,7 +34,7 @@ final class LifterLMS {
*
* @var string
*/
- public $version = '7.7.5';
+ public $version = '7.7.6';
/**
* LLMS_Assets instance
diff --git a/includes/abstracts/abstract.llms.database.query.php b/includes/abstracts/abstract.llms.database.query.php
index 3bd2df44ca..1ce8bfc71e 100644
--- a/includes/abstracts/abstract.llms.database.query.php
+++ b/includes/abstracts/abstract.llms.database.query.php
@@ -232,7 +232,6 @@ protected function sql_limit() {
* @return string
*/
protected function sql_orderby() {
-
$sql = '';
$sort = $this->get( 'sort' );
@@ -244,7 +243,7 @@ protected function sql_orderby() {
foreach ( $sort as $orderby => $order ) {
$pre = ( $comma ) ? ', ' : ' ';
- $sql .= $pre . "{$orderby} {$order}";
+ $sql .= $pre . sanitize_sql_orderby( "{$orderby} {$order}" );
$comma = true;
}
}
diff --git a/includes/admin/settings/class.llms.settings.accounts.php b/includes/admin/settings/class.llms.settings.accounts.php
index 840b7a94bb..545153f00d 100644
--- a/includes/admin/settings/class.llms.settings.accounts.php
+++ b/includes/admin/settings/class.llms.settings.accounts.php
@@ -71,7 +71,8 @@ public function get_settings() {
'class' => 'llms-select2-post',
'type' => 'select',
'custom_attributes' => array(
- 'data-post-type' => 'page',
+ 'data-post-type' => 'page',
+ 'data-placeholder' => __( 'Select a page', 'lifterlms' ),
),
'options' => llms_make_select2_post_array( get_option( 'lifterlms_myaccount_page_id', '' ) ),
),
@@ -372,7 +373,6 @@ public function get_settings() {
* @param array $account_settings The account page settings.
*/
return apply_filters( "lifterlms_{$this->id}_settings", $account_settings );
-
}
/**
@@ -385,7 +385,6 @@ public function get_settings() {
protected function set_label() {
return __( 'Accounts', 'lifterlms' );
}
-
}
return new LLMS_Settings_Accounts();
diff --git a/includes/class-llms-media-protector.php b/includes/class-llms-media-protector.php
index 53fc87a4b3..727668687b 100644
--- a/includes/class-llms-media-protector.php
+++ b/includes/class-llms-media-protector.php
@@ -648,9 +648,11 @@ public function save_mod_rewrite_rules() {
$rules = "Options -Indexes\n";
$rules .= "deny from all\n";
- if ( false === $wp_filesystem->exists( $htaccess_file ) ) {
+ if ( $upload_path_writeable && ! $wp_filesystem->exists( $htaccess_file ) ) {
+ $wp_filesystem->put_contents( $htaccess_file, $rules, 0644 );
+ } elseif ( $upload_path_writeable ) {
$contents = $wp_filesystem->get_contents( $htaccess_file );
- if ( $upload_path_writeable && ( ! $contents || $contents !== $rules ) ) {
+ if ( $contents !== $rules ) {
$wp_filesystem->put_contents( $htaccess_file, $rules, 0644 );
}
}
diff --git a/includes/class.llms.person.handler.php b/includes/class.llms.person.handler.php
index 99373a561f..47efa3aa9d 100644
--- a/includes/class.llms.person.handler.php
+++ b/includes/class.llms.person.handler.php
@@ -86,7 +86,6 @@ protected static function find_password_fields( $location ) {
}
return $fields;
-
}
/**
@@ -120,7 +119,7 @@ public static function generate_username( $email ) {
while ( username_exists( $username ) ) {
$username = $orig_username . $i;
- $i++;
+ ++$i;
}
@@ -133,7 +132,6 @@ public static function generate_username( $email ) {
* @param string $email User's email address which was used to generate the username.
*/
return apply_filters( 'lifterlms_generated_username', $username, $email );
-
}
/**
@@ -196,13 +194,12 @@ public static function get_login_fields( $layout = 'columns' ) {
'columns' => ( 'columns' == $layout ) ? 3 : 6,
'id' => 'llms_lost_password',
'last_column' => true,
- 'description' => '' . __( 'Lost your password?', 'lifterlms' ) . '',
+ 'description' => '' . __( 'Lost your password?', 'lifterlms' ) . '',
'type' => 'html',
'wrapper_classes' => 'align-right',
),
)
);
-
}
/**
@@ -264,7 +261,6 @@ public static function get_lost_password_fields() {
),
)
);
-
}
/**
@@ -313,7 +309,6 @@ private static function get_password_fields() {
);
return $fields;
-
}
/**
@@ -381,7 +376,6 @@ public static function get_password_reset_fields( $key = '', $login = '' ) {
* set of fields is generated programmatically.
*/
return apply_filters( 'llms_password_reset_fields', $fields, $key, $login, $location );
-
}
/**
@@ -483,7 +477,6 @@ public static function login( $data ) {
}
return $signon->ID;
-
}
/**
@@ -533,7 +526,6 @@ protected static function validate_login_fields( $data ) {
* @param array $data User submitted login data.
*/
return apply_filters( 'llms_after_user_login_data_validation', $valid, $data );
-
}
/**
@@ -551,5 +543,4 @@ public static function get_available_fields( $screen = 'registration', $data = a
_deprecated_function( 'LLMS_Person_Handler::get_available_fields()', '5.0.0', 'LLMS_Forms::get_form_fields()' );
return LLMS_Forms::instance()->get_form_fields( $screen );
}
-
}
diff --git a/includes/emails/class.llms.email.reset.password.php b/includes/emails/class.llms.email.reset.password.php
index 17e556e94f..390277ab7e 100644
--- a/includes/emails/class.llms.email.reset.password.php
+++ b/includes/emails/class.llms.email.reset.password.php
@@ -41,7 +41,6 @@ public function init( $args = array() ) {
'{user_login}' => $args['login_display'],
)
);
-
}
/**
@@ -60,7 +59,7 @@ public function get_body_content( $data ) {
'key' => $data['key'],
'login' => rawurlencode( $data['user']->user_login ),
),
- llms_lostpassword_url()
+ wp_lostpassword_url()
)
);
@@ -72,7 +71,5 @@ public function get_body_content( $data ) {
)
);
return ob_get_clean();
-
}
-
}
diff --git a/includes/forms/controllers/class.llms.controller.account.php b/includes/forms/controllers/class.llms.controller.account.php
index 847fdba1e0..4967d4ed52 100644
--- a/includes/forms/controllers/class.llms.controller.account.php
+++ b/includes/forms/controllers/class.llms.controller.account.php
@@ -37,7 +37,6 @@ public function __construct() {
add_action( 'init', array( $this, 'reset_password' ) );
add_action( 'init', array( $this, 'cancel_subscription' ) );
add_action( 'init', array( $this, 'redeem_voucher' ) );
-
}
/**
@@ -88,7 +87,6 @@ public function cancel_subscription() {
* @param integer $uid The WP_User ID the student who cancelled the subscription.
*/
do_action( 'llms_subscription_cancelled_by_student', $order, $uid );
-
}
/**
@@ -135,7 +133,6 @@ public function update() {
llms_redirect_and_exit( apply_filters( 'lifterlms_update_account_redirect', llms_get_endpoint_url( 'edit-account', '', llms_get_page_url( 'myaccount' ) ) ) );
}
-
}
/**
@@ -247,7 +244,6 @@ public function lost_password() {
// Success.
llms_add_notice( __( 'Check your e-mail for the confirmation link.', 'lifterlms' ) );
return true;
-
}
/**
@@ -275,7 +271,6 @@ public function redeem_voucher() {
llms_add_notice( __( 'Voucher redeemed successfully!', 'lifterlms' ), 'success' );
return true;
-
}
/**
@@ -306,7 +301,6 @@ public function reset_password() {
// Success.
llms_add_notice( __( 'Your password has been updated.', 'lifterlms' ) );
llms_redirect_and_exit( add_query_arg( 'password-reset', 1, llms_get_page_url( 'myaccount' ) ) );
-
}
/**
@@ -377,7 +371,6 @@ private function reset_password_handler() {
do_action( 'llms_user_password_reset', $user );
return true;
-
}
/**
@@ -403,9 +396,8 @@ public function reset_password_link_redirect() {
( new LLMS_Cache_Helper() )->maybe_no_cache();
llms_set_password_reset_cookie( $val );
- llms_redirect_and_exit( add_query_arg( 'reset-pass', 1, llms_lostpassword_url() ) );
+ llms_redirect_and_exit( add_query_arg( 'reset-pass', 1, wp_lostpassword_url() ) );
}
-
}
/**
@@ -452,9 +444,7 @@ protected function validate_password_reset( $posted_data ) {
}
return true;
-
}
-
}
return new LLMS_Controller_Account();
diff --git a/includes/functions/llms.functions.page.php b/includes/functions/llms.functions.page.php
index b1d9f4327e..b3a194143e 100644
--- a/includes/functions/llms.functions.page.php
+++ b/includes/functions/llms.functions.page.php
@@ -21,7 +21,6 @@ function llms_cancel_payment_url() {
$cancel_payment_url = esc_url( get_permalink( llms_get_page_id( 'checkout' ) ) );
return apply_filters( 'lifterlms_checkout_confirm_payment_url', $cancel_payment_url );
-
}
/**
@@ -59,7 +58,6 @@ function llms_confirm_payment_url( $order_key = null ) {
* @param string $url URL to the payment confirmation screen.
*/
return apply_filters( 'lifterlms_checkout_confirm_payment_url', $url );
-
}
/**
@@ -180,7 +178,6 @@ function _llms_normalize_endpoint_base_url( $url, $endpoint ) {
}
return $url;
-
}
/**
@@ -221,7 +218,6 @@ function llms_get_page_id( $page ) {
$page = apply_filters( "lifterlms_get_{$page}_page_id", $id );
return $page ? absint( $page ) : -1;
-
}
@@ -249,10 +245,14 @@ function llms_get_page_url( $page, $args = array() ) {
*
* @return string
*/
-function llms_lostpassword_url() {
+function llms_lostpassword_url( $lostpassword_url ) {
+ if ( llms_get_page_id( 'myaccount' ) <= 0 || ! get_permalink( llms_get_page_id( 'myaccount' ) ) ) {
+ return $lostpassword_url;
+ }
+
return llms_get_endpoint_url( 'lost-password', '', get_permalink( llms_get_page_id( 'myaccount' ) ) );
}
-add_filter( 'lostpassword_url', 'llms_lostpassword_url', 10, 0 );
+add_filter( 'lostpassword_url', 'llms_lostpassword_url', 10, 1 );
/**
* Returns the page number query var for the current request.
@@ -278,5 +278,4 @@ function llms_get_paged_query_var() {
$paged = 1;
}
return (int) $paged;
-
}
diff --git a/includes/notifications/class.llms.notifications.query.php b/includes/notifications/class.llms.notifications.query.php
index eefa9d5896..abeb5ae61f 100644
--- a/includes/notifications/class.llms.notifications.query.php
+++ b/includes/notifications/class.llms.notifications.query.php
@@ -94,7 +94,6 @@ protected function get_default_args() {
* @param LLMS_Notifications_Query $notifications_query Instance of `LLMS_Notifications_Query`.
*/
return apply_filters( 'llms_notifications_query_default_args', $args, $this );
-
}
/**
@@ -139,7 +138,6 @@ public function get_notifications() {
* @param LLMS_Notifications_Query $notifications_query Instance of `LLMS_Notifications_Query`.
*/
return apply_filters( 'llms_notifications_query_get_notifications', $notifications, $this );
-
}
/**
@@ -153,7 +151,6 @@ protected function parse_args() {
$this->parse_statuses();
$this->parse_types();
-
}
/**
@@ -176,7 +173,6 @@ private function parse_statuses() {
$statuses = array_intersect( $statuses, $this->get_available_statuses() );
$this->arguments['statuses'] = $statuses;
-
}
/**
@@ -198,7 +194,6 @@ private function parse_types() {
// ensure only valid types are used
$types = array_intersect( $types, $this->get_available_types() );
$this->arguments['types'] = $types;
-
}
/**
@@ -218,7 +213,6 @@ private function parse_triggers() {
}
$this->arguments['triggers'] = $triggers;
-
}
/**
@@ -254,7 +248,6 @@ protected function prepare_query() {
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
return $sql;
-
}
/**
@@ -275,7 +268,7 @@ protected function sql_orderby() {
foreach ( $this->get( 'sort' ) as $orderby => $order ) {
$pre = ( $comma ) ? ', ' : ' ';
- $sql .= $pre . "n.{$orderby} {$order}";
+ $sql .= $pre . 'n.' . sanitize_sql_orderby( "{$orderby} {$order}" );
$comma = true;
}
@@ -292,7 +285,6 @@ protected function sql_orderby() {
* @param LLMS_Notifications_Query $notifications_query Instance of LLMS_Events_Query.
*/
return apply_filters( 'llms_notifications_query_where', $sql, $this );
-
}
/**
@@ -344,7 +336,5 @@ private function sql_where() {
}
return $where;
-
}
-
}
diff --git a/includes/notifications/views/class.llms.notification.view.student.welcome.php b/includes/notifications/views/class.llms.notification.view.student.welcome.php
index 60c6eed9f6..98cf7bb1ed 100644
--- a/includes/notifications/views/class.llms.notification.view.student.welcome.php
+++ b/includes/notifications/views/class.llms.notification.view.student.welcome.php
@@ -100,7 +100,7 @@ protected function set_merge_data( $code ) {
break;
case '{{PASSWORD_RESET_URL}}':
- $code = llms_lostpassword_url();
+ $code = wp_lostpassword_url();
break;
case '{{SITE_TITLE}}':
diff --git a/includes/shortcodes/class.llms.shortcode.membership.link.php b/includes/shortcodes/class.llms.shortcode.membership.link.php
index bfcc8030c5..f5860f095b 100644
--- a/includes/shortcodes/class.llms.shortcode.membership.link.php
+++ b/includes/shortcodes/class.llms.shortcode.membership.link.php
@@ -40,6 +40,10 @@ class LLMS_Shortcode_Membership_Link extends LLMS_Shortcode {
* @version 3.4.3
*/
protected function get_output() {
+ if ( 'publish' !== get_post_status( $this->get_attribute( 'id' ) ) ) {
+ return '';
+ }
+
return '' . $this->get_content() . '';
}
@@ -65,9 +69,9 @@ protected function get_default_attributes() {
* @version 3.4.3
*/
protected function get_default_content( $atts = array() ) {
- return apply_filters( 'lifterlms_membership_link_text', get_the_title( $this->get_attribute( 'id' ) ), $this->get_attribute( 'id' ) );
+ $default_content = 'publish' === get_post_status( $this->get_attribute( 'id' ) ) ? get_the_title( $this->get_attribute( 'id' ) ) : '';
+ return apply_filters( 'lifterlms_membership_link_text', $default_content, $this->get_attribute( 'id' ) );
}
-
}
return LLMS_Shortcode_Membership_Link::instance();
diff --git a/lifterlms.php b/lifterlms.php
index c80a3fb37b..d228d71ef0 100644
--- a/lifterlms.php
+++ b/lifterlms.php
@@ -10,7 +10,7 @@
* Plugin Name: LifterLMS
* Plugin URI: https://lifterlms.com/
* Description: Complete e-learning platform to sell online courses, protect lessons, offer memberships, and quiz students. WP Learning Management System.
- * Version: 7.7.5
+ * Version: 7.7.6
* Author: LifterLMS
* Author URI: https://lifterlms.com/
* Text Domain: lifterlms
diff --git a/package-lock.json b/package-lock.json
index 415e07a609..b3b36a9169 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "lifterlms",
- "version": "7.7.5",
+ "version": "7.7.6",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "lifterlms",
- "version": "7.7.5",
+ "version": "7.7.6",
"license": "GPL-3.0",
"dependencies": {
"@babel/core": "^7.16.5",
diff --git a/package.json b/package.json
index e649f6fa59..1259e41990 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "lifterlms",
- "version": "7.7.5",
+ "version": "7.7.6",
"description": "LifterLMS by codeBOX",
"repository": {
"type": "git",
diff --git a/templates/quiz/results-attempt-questions-list.php b/templates/quiz/results-attempt-questions-list.php
index 9fba3c9080..f7dc3b7050 100644
--- a/templates/quiz/results-attempt-questions-list.php
+++ b/templates/quiz/results-attempt-questions-list.php
@@ -45,7 +45,7 @@