Skip to content

Commit 51b2d3b

Browse files
authored
Merge pull request #3081 from gocodebox/dev
Release 9.2.0
2 parents 89d2154 + f2d974a commit 51b2d3b

30 files changed

+384
-123
lines changed

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,35 @@
11
LifterLMS Changelog
22
===================
33

4+
v9.2.0 - 2026-01-15
5+
-------------------
6+
7+
##### New Features
8+
9+
+ Adding "Order (High to Low)" sorting option for the Course and Membership Catalog. [#3074](https://github.com/gocodebox/lifterlms/issues/3074)
10+
+ New global and course-level option to specify a page to redirect to upon course completion.
11+
+ Ability to edit pricing for future charges of a recurring Order.
12+
13+
##### Updates and Enhancements
14+
15+
+ Renaming "Basic" notification to "Popup" for clarity.
16+
+ Avoid showing license key on error.
17+
18+
##### Bug Fixes
19+
20+
+ Additional verifications when checking for an Elementor post to avoid fatal errors in some cases. [#3065](https://github.com/gocodebox/lifterlms/issues/3065)
21+
+ Allow selection of all categories in the Courses block when there are more than 10 categories. [#3078](https://github.com/gocodebox/lifterlms/issues/3078)
22+
+ Fixing aria label output for course favorites. Thanks [@DAnn2012](https://github.com/DAnn2012)!
23+
+ Avoid fatal error when importing a course with an empty picture choice question. [#3070](https://github.com/gocodebox/lifterlms/issues/3070)
24+
+ Fix protected images not loading on WPEngine hosting. [#3048](https://github.com/gocodebox/lifterlms/issues/3048)
25+
+ Fix count of currently enrolled students in the Course overview reporting for certain hosts and number of students. [#3073](https://github.com/gocodebox/lifterlms/issues/3073)
26+
+ Handle possible array of arrays in admin settings.
27+
28+
##### Updated Templates
29+
30+
+ [templates/course/favorite.php](https://github.com/gocodebox/lifterlms/blob/9.2.0/templates/course/favorite.php)
31+
32+
433
v9.1.2 - 2025-11-20
534
-------------------
635

assets/js/private/llms-metaboxes.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,26 @@
367367
$input.append( '<em>:</em>' );
368368
$input.append( '<input class="llms-time-input" max="59" min="0" name="' + name + '[minute]" type="number" value="' + val.minute + '">' );
369369

370-
} else {
370+
} else if ( 'price' === type ) {
371+
372+
$input = $( '<input>' )
373+
.attr('name', name)
374+
.attr('type', 'number')
375+
.attr('min', '0')
376+
.attr('step', 'any')
377+
.attr('value', val);
378+
if (required) {
379+
$input.attr('required', 'required');
380+
}
371381

372-
$input = $( '<input name="' + name + '" type="' + type + '" value="' + val + '"' + required + '>' );
382+
} else {
383+
$input = $( '<input>' )
384+
.attr('name', name)
385+
.attr('type', type)
386+
.attr('value', val);
387+
if (required) {
388+
$input.attr('required', 'required');
389+
}
373390
}
374391

375392
$field.empty().append( $label ).append( $input );

class-lifterlms.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ final class LifterLMS {
3434
*
3535
* @var string
3636
*/
37-
public $version = '9.1.2';
37+
public $version = '9.2.0';
3838

3939
/**
4040
* LLMS_Assets instance

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"deliciousbrains/wp-background-processing": "1.0.2",
3232
"lifterlms/lifterlms-blocks": "2.7.0",
3333
"lifterlms/lifterlms-cli": "0.0.5",
34-
"lifterlms/lifterlms-helper": "3.5.6",
34+
"lifterlms/lifterlms-helper": "3.5.7",
3535
"lifterlms/lifterlms-rest": "1.0.3",
3636
"woocommerce/action-scheduler": "3.5.4",
3737
"gocodebox/banner-notifications": "1.1.1"

includes/abstracts/abstract.llms.database.query.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ protected function found_results() {
174174
*/
175175
protected function sql_select_columns( $select_columns = '*' ) {
176176

177-
if ( ! $this->get( 'no_found_rows' ) ) {
177+
if ( ! $this->get( 'count_only' ) && ! $this->get( 'no_found_rows' ) ) {
178178
$select_columns = 'SQL_CALC_FOUND_ROWS ' . $select_columns;
179179
}
180180

@@ -234,6 +234,11 @@ protected function sql_limit() {
234234
protected function sql_orderby() {
235235
$sql = '';
236236

237+
// No point in ordering if we're just counting.
238+
if ( $this->get( 'count_only' ) ) {
239+
return $sql;
240+
}
241+
237242
$sort = $this->get( 'sort' );
238243
if ( $sort ) {
239244

includes/abstracts/llms-abstract-query.php

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ public function __construct( $args = array() ) {
129129
$this->setup_args();
130130

131131
$this->query();
132-
133132
}
134133

135134
/**
@@ -148,7 +147,6 @@ protected function count_results() {
148147
$this->found_results = $this->found_results();
149148
$this->max_pages = absint( ceil( $this->found_results / $this->get( 'per_page' ) ) );
150149
}
151-
152150
}
153151

154152
/**
@@ -170,8 +168,8 @@ protected function default_arguments() {
170168
'sort' => array(),
171169
'suppress_filters' => false,
172170
'no_found_rows' => false,
171+
'count_only' => false,
173172
);
174-
175173
}
176174

177175
/**
@@ -275,7 +273,6 @@ protected function get_allowed_sort_fields() {
275273
* @param array $allowed_fields Default arguments.
276274
*/
277275
return apply_filters( "llms_{$this->id}_query_allowed_sort_fields", $allowed_fields );
278-
279276
}
280277

281278
/**
@@ -302,7 +299,6 @@ protected function get_default_args() {
302299
* @param array $args Array of default arguments to set up the query with.
303300
*/
304301
return apply_filters( "llms_{$this->id}_query_get_default_args", $this->default_arguments() );
305-
306302
}
307303

308304
/**
@@ -375,7 +371,6 @@ public function get_results() {
375371
* @param array $results Array of results retrieved by the query.
376372
*/
377373
return apply_filters( "llms_{$this->id}_query_get_results", $this->results );
378-
379374
}
380375

381376
/**
@@ -474,7 +469,6 @@ public function query() {
474469
$this->results = $this->perform_query();
475470

476471
$this->count_results();
477-
478472
}
479473

480474
/**
@@ -501,7 +495,6 @@ protected function sanitize_id_array( $ids = array() ) {
501495

502496
// Remove empty values.
503497
return array_values( array_filter( $ids ) );
504-
505498
}
506499

507500
/**
@@ -528,7 +521,6 @@ protected function sanitize_sort( $sort ) {
528521
}
529522

530523
return $sort;
531-
532524
}
533525

534526
/**
@@ -583,7 +575,25 @@ protected function setup_args() {
583575
$this->set( $arg, $val );
584576

585577
}
586-
587578
}
588579

580+
public function get_count_only_result() {
581+
$results = $this->get_results();
582+
if ( ! is_array( $results ) || ! count( $results ) || ! isset( $results[0] ) || ! property_exists(
583+
$results[0],
584+
'total'
585+
) ) {
586+
/* Translators: %s - name of class. */
587+
error_log(
588+
sprintf(
589+
__( '[LifterLMS] Found results with count_only has no result rows in %s.', 'lifterlms' ),
590+
get_class( $this )
591+
)
592+
);
593+
594+
return 0;
595+
}
596+
597+
return intval( $results[0]->total );
598+
}
589599
}

includes/abstracts/llms.abstract.notification.controller.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,7 @@ public function send_test( $type, $data = array() ) {
596596
*/
597597
protected function set_supported_types() {
598598
return array(
599-
'basic' => __( 'Basic', 'lifterlms' ),
599+
'basic' => __( 'Popup', 'lifterlms' ),
600600
'email' => __( 'Email', 'lifterlms' ),
601601
);
602602
}

includes/admin/class.llms.admin.settings.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ public static function get_option( $option_name, $default = '' ) {
918918
}
919919

920920
if ( is_array( $option_value ) ) {
921-
$option_value = array_map( 'stripslashes', $option_value );
921+
$option_value = stripslashes_deep( $option_value );
922922
} elseif ( ! is_null( $option_value ) ) {
923923
$option_value = stripslashes( $option_value );
924924
}

includes/admin/post-types/meta-boxes/class.llms.meta.box.course.options.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,21 @@ public function get_fields() {
184184
'class' => 'code input-full',
185185
'value' => 'test',
186186
),
187+
array(
188+
'label' => __( 'Course Completion Page', 'lifterlms' ),
189+
'class' => 'llms-select2-post',
190+
'data_attributes' => array(
191+
'allow-clear' => true,
192+
'post-type' => 'page',
193+
'placeholder' => get_option( 'lifterlms_course_completion_page_id', '' ) ?
194+
sprintf( __( 'Global setting (%s)', 'lifterlms' ), get_the_title( get_option( 'lifterlms_course_completion_page_id' ) ) ) :
195+
__( 'Global setting (none)', 'lifterlms' ),
196+
),
197+
'desc' => sprintf( __( 'This page will be shown to students when they complete the course. %1$sMore Information%2$s', 'lifterlms' ), '<a href="https://lifterlms.com/docs/course-completion-page/" target="_blank">', '</a>' ),
198+
'id' => $this->prefix . 'completion_page_id',
199+
'value' => llms_make_select2_post_array( array( $course->get( 'completion_page_id' ) ) ),
200+
'type' => 'select',
201+
),
187202
),
188203
),
189204
array(

includes/admin/post-types/meta-boxes/class.llms.meta.box.order.details.php

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ public function configure() {
3333
);
3434
$this->context = 'normal';
3535
$this->priority = 'high';
36-
3736
}
3837

3938
/**
@@ -75,7 +74,6 @@ public function output() {
7574
}
7675

7776
include LLMS_PLUGIN_DIR . 'includes/admin/views/metaboxes/view-order-details.php';
78-
7977
}
8078

8179
/**
@@ -102,6 +100,10 @@ public function save( $post_id ) {
102100
return 0;
103101
}
104102

103+
if ( ! current_user_can( 'edit_post', $post_id ) ) {
104+
return -1;
105+
}
106+
105107
$fields = array(
106108
'payment_gateway',
107109
'gateway_customer_id',
@@ -116,10 +118,16 @@ public function save( $post_id ) {
116118
}
117119
}
118120

121+
// Only allow editing the total (for the next recurrence) if this is a recurring order.
122+
if ( $order->is_recurring() && isset( $_POST['total'] ) && is_numeric( $_POST['total'] ) ) {
123+
$total = floatval( $_POST['total'] );
124+
$order->set( 'total', $total );
125+
$order->add_note( sprintf( __( 'Order total for future payments updated to %s.', 'lifterlms' ), $order->get_price( 'total' ) ) );
126+
}
127+
119128
$this->save_remaining_payments( $order );
120129

121130
return 1;
122-
123131
}
124132

125133
/**
@@ -181,7 +189,5 @@ protected function save_remaining_payments( $order ) {
181189
}
182190

183191
return 1;
184-
185192
}
186-
187193
}

0 commit comments

Comments
 (0)