Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changelogs/fix_ending-course-calc-processor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
significance: patch
type: fixed
links:
- "#3087"
entry: Fix course data calculation not ending since 9.2.0.
94 changes: 94 additions & 0 deletions includes/functions/updates/llms-functions-updates-921.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php
/**
* Update functions for version 9.2.1
*
* @package LifterLMS/Functions/Updates
*
* @since 9.2.1
*/

namespace LLMS\Updates\Version_9_2_1;

defined( 'ABSPATH' ) || exit;

/**
* Retrieves the DB version of the migration.
*
* @since 9.2.1
*
* @return string
*/
function _get_db_version() {
return '9.2.1';
}

/**
* Clear stale course data locks and re-schedule course data processing.
*
* Finds all `_llms_temp_calc_data_lock` postmeta entries, deletes them, and
* triggers `llms_course_calculate_data` for each affected course.
*
* Returns `true` if there may be more records to process so the background
* updater can call this again, otherwise `false` when done.
*
* @since 9.2.1
*
* @return bool
*/
function reset_course_calc_data_locks() {

global $wpdb;

$per_page = \llms_update_util_get_items_per_page();

// Find a page of locked courses.
$course_ids = $wpdb->get_col(
$wpdb->prepare(
"
SELECT DISTINCT pm.post_id
FROM {$wpdb->postmeta} AS pm
INNER JOIN {$wpdb->posts} AS p
ON p.ID = pm.post_id
WHERE pm.meta_key = %s
AND p.post_type = %s
LIMIT %d
",
'_llms_temp_calc_data_lock',
'course',
$per_page
)
);// db call ok; no-cache ok.

if ( empty( $course_ids ) ) {
return false;
}

foreach ( $course_ids as $course_id ) {

$course_id = (int) $course_id;

// Drop the temp lock meta.
\delete_post_meta( $course_id, '_llms_temp_calc_data_lock' );

// Kick off a fresh course data calculation round.
// LLMS_Processor_Course_Data::schedule_calculation() is already
// wired to this action and internally avoids duplicate scheduling
// via wp_next_scheduled().
\do_action( 'llms_course_calculate_data', $course_id );
}

// If there were $per_page results, assume there might be more.
return ( count( $course_ids ) === $per_page );
}

/**
* Update db version to 9.2.1.
*
* @since 9.2.1
*
* @return false
*/
function update_db_version() {
\LLMS_Install::update_db_version( _get_db_version() );
return false;
}
40 changes: 38 additions & 2 deletions includes/processors/class.llms.processor.course.data.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public function dispatch_calc( $course_id ) {
}

// Get the total number of students as a separate query since deprecating SQL_CALC_FOUND_ROWS usage.
$count_query = new LLMS_Student_Query( array_merge( $args, array( 'count_only' => true ) ) );
$count_query = new LLMS_Student_Query( $this->get_student_count_query_from_args( $args ) );
if ( ! $count_query->get_count_only_result() ) {
return $this->task_complete( $course, $this->get_task_data(), true );
}
Expand All @@ -121,6 +121,8 @@ public function dispatch_calc( $course_id ) {

// Add each page to the queue.
$max_pages = absint( ceil( $count_query->get_count_only_result() / $args['per_page'] ) );
// Pass in the max pages as an argument to the task so we don't need to run the count query each time.
$args['max_pages'] = $max_pages;
while ( $args['page'] <= $max_pages ) {
$this->push_to_queue( $args );
++$args['page'];
Expand All @@ -147,6 +149,19 @@ protected function dispatch_calc_throttled( $course_id ) {
$this->log( sprintf( 'Course data calculation throttled for course %d.', $course_id ) );
}

/**
* Modify the query arguments for calculating the total count.
*
* @param $args
*
* @return array Array of arguments passed to an LLMS_Student_Query for calculating the student count.
*/
protected function get_student_count_query_from_args( $args ) {
$count_args = array_merge( $args, array( 'count_only' => true ) );

return $count_args;
}

/**
* Retrieve arguments used to perform an LLMS_Student_Query for background data processing
*
Expand Down Expand Up @@ -444,6 +459,15 @@ public function task( $args ) {
// Merge with the defaults.
$data = $this->get_task_data( $data );

/**
* Save the max number of pages value passed in when the tasks were pushed to the queue.
*
* If a task was dispatched without it, set the max pages to 0 so we can try to calculate the count
* using a new count-only query.
*/
$max_pages = isset( $args['max_pages'] ) ? $args['max_pages'] : 0;
unset( $args['max_pages'] );

// Perform the query.
$query = new LLMS_Student_Query( $args );

Expand All @@ -464,7 +488,19 @@ public function task( $args ) {
}
}

return $this->task_complete( $course, $data, $query->is_last_page() );
if ( $max_pages === 0 ) {
$count_query = new LLMS_Student_Query( $this->get_student_count_query_from_args( $args ) );
if ( ! $count_query->get_count_only_result() ) {
// End processing when we can't get the count.
$is_last_page = true;
return $this->task_complete( $course, $data, $is_last_page );
}

$max_pages = absint( ceil( $count_query->get_count_only_result() / $args['per_page'] ) );
}
$is_last_page = ( absint( $max_pages ) === absint( $args['page'] ) );

return $this->task_complete( $course, $data, $is_last_page );
}

/**
Expand Down
8 changes: 8 additions & 0 deletions includes/schemas/llms-db-updates.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,4 +204,12 @@
'update_db_version',
),
),
'9.2.1' => array(
'type' => 'auto',
'namespace' => true,
'updates' => array(
'reset_course_calc_data_locks',
'update_db_version',
),
),
);
Loading