Home / Admin / LifterLMS_DIR_AC_SYNC – LifterLMS Content Sync Engine – Comprehensive Data Version
Duplicate Snippet

Embed Snippet on Your Site

LifterLMS_DIR_AC_SYNC – LifterLMS Content Sync Engine – Comprehensive Data Version

* LifterLMS Content Sync Engine - Comprehensive Data Version
* Syncs courses ONLY with ALL related content stored within course records
* Integrates with detail population and edit links
* WPCode Snippet - Run Everywhere - Priority 20
*/

ismail daugherty PRO
<10
Code Preview
php
<?php
/**
 * LifterLMS Content Sync Engine - Comprehensive Data Version
 * Syncs courses ONLY with ALL related content stored within course records
 * Integrates with detail population and edit links
 * WPCode Snippet - Run Everywhere - Priority 20
 */
defined( 'ABSPATH' ) || exit;
// Add manual sync button in admin bar
add_action( 'admin_bar_menu', function( $wp_admin_bar ) {
    if ( ! current_user_can( 'manage_options' ) ) return;
    
    $wp_admin_bar->add_node( [
        'id'    => 'llms-content-sync',
        'title' => '🔄 Sync LMS Content',
        'href'  => wp_nonce_url(
            admin_url( 'admin.php?llms_content_sync=1' ),
            'llms_content_sync'
        ),
    ] );
}, 999 );
// Handle manual sync trigger
add_action( 'admin_init', function() {
    if ( ! isset( $_GET['llms_content_sync'] ) ) return;
    if ( ! current_user_can( 'manage_options' ) ) wp_die( 'Unauthorized' );
    if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'llms_content_sync' ) ) wp_die( 'Invalid nonce' );
    
    // Check if LifterLMS is active
    if ( ! class_exists( 'LifterLMS' ) ) {
        wp_die( 'LifterLMS is not active!' );
    }
    
    // Check for stale lock (older than 10 minutes)
    $lock_time = get_option( '_transient_timeout_llms_content_sync_lock' );
    if ( $lock_time && $lock_time < time() ) {
        // Lock is expired but not cleaned up, delete it
        delete_transient( 'llms_content_sync_lock' );
    }
    
    // Prevent concurrent syncs
    if ( get_transient( 'llms_content_sync_lock' ) ) {
        // Check if lock is stale (shouldn't happen after above check, but just in case)
        $lock_set_time = get_option( 'llms_content_sync_lock_time', 0 );
        if ( $lock_set_time && ( time() - $lock_set_time ) > 600 ) { // 10 minutes
            // Force clear stale lock
            delete_transient( 'llms_content_sync_lock' );
            delete_option( 'llms_content_sync_lock_time' );
        } else {
            wp_die( 'A sync is already in progress. Please wait. If this persists for more than 10 minutes, the lock will auto-clear.' );
        }
    }
    
    // Set lock for 10 minutes
    set_transient( 'llms_content_sync_lock', true, 10 * MINUTE_IN_SECONDS );
    update_option( 'llms_content_sync_lock_time', time() );
    
    try {
        // Clean up orphaned content first
        llms_content_cleanup_orphaned();
        
        // Perform sync
        $result = llms_content_sync_all();
        
        // Clear lock and timestamp
        delete_transient( 'llms_content_sync_lock' );
        delete_option( 'llms_content_sync_lock_time' );
        
        // Redirect with results
        wp_redirect( admin_url( 'edit.php?post_type=llms_content_sync&synced=' . $result['total'] ) );
        exit;
        
    } catch ( Exception $e ) {
        // Always clear lock on error
        delete_transient( 'llms_content_sync_lock' );
        delete_option( 'llms_content_sync_lock_time' );
        wp_die( 'Sync failed: ' . esc_html( $e->getMessage() ) );
    }
} );
// Show success message
add_action( 'admin_notices', function() {
    if ( isset( $_GET['synced'] ) && $_GET['post_type'] === 'llms_content_sync' ) {
        $count = intval( $_GET['synced'] );
        echo '<div class="notice notice-success"><p>✅ Synced ' . $count . ' courses!</p></div>';
    }
} );
/**
 * Clean up orphaned content
 */
function llms_content_cleanup_orphaned() {
    // Get all synced content
    $synced_posts = new WP_Query( [
        'post_type'      => 'llms_content_sync',
        'posts_per_page' => -1,
        'fields'         => 'ids',
    ] );
    
    $deleted_count = 0;
    
    foreach ( $synced_posts->posts as $post_id ) {
        $item_id = intval( get_post_meta( $post_id, 'item_id', true ) );
        $content_type = get_post_meta( $post_id, 'content_type', true );
        
        // Check if original item still exists
        $exists = false;
        
        if ( $content_type === 'course' ) {
            $exists = ( get_post_status( $item_id ) !== false );
        }
        
        if ( ! $exists ) {
            wp_delete_post( $post_id, true );
            $deleted_count++;
            error_log( "LLMS_SYNC: Deleted orphaned course (post {$post_id})" );
        }
    }
    
    if ( $deleted_count > 0 ) {
        error_log( "LLMS_SYNC: Cleaned up {$deleted_count} orphaned items" );
    }
}
/**
 * Main sync function - ONLY SYNCS COURSES
 */
function llms_content_sync_all() {
    $counts = [
        'courses' => 0,
        'total' => 0
    ];
    
    // Get all courses
    $courses_query = new WP_Query( [
        'post_type'      => 'course',
        'posts_per_page' => -1,
        'post_status'    => 'any',
    ] );
    
    foreach ( $courses_query->posts as $course_post ) {
        $course = llms_get_post( $course_post->ID );
        
        // Sync course with comprehensive data (includes all lesson data)
        $course_sync_id = llms_content_sync_item( [
            'content_type' => 'course',
            'item_id'      => $course->get( 'id' ),
            'title'        => $course->get( 'title' ),
            'data'         => llms_content_prepare_comprehensive_course_data( $course )
        ] );
        
        if ( $course_sync_id ) {
            $counts['courses']++;            
            
            // Trigger detail population hook to add additional details
            do_action( 'llms_content_sync_complete', $course->get( 'id' ), $course_sync_id, true );
        }
    }
    
    $counts['total'] = $counts['courses'];
    
    error_log( "LLMS_SYNC: Synced {$counts['courses']} courses" );
    
    return $counts;
}
/**
 * Sync individual item
 */
function llms_content_sync_item( $args ) {
    // Check if post exists
    $existing_query = new WP_Query( [
        'post_type'      => 'llms_content_sync',
        'posts_per_page' => 1,
        'fields'         => 'ids',
        'meta_query'     => [
            'relation' => 'AND',
            [
                'key'   => 'content_type',
                'value' => $args['content_type'],
            ],
            [
                'key'   => 'item_id',
                'value' => $args['item_id'],
            ]
        ]
    ] );
    
    $post_data = [
        'post_type'   => 'llms_content_sync',
        'post_status' => 'publish',
        'post_title'  => $args['title'],
    ];
    
    if ( $existing_query->have_posts() ) {
        $post_data['ID'] = $existing_query->posts[0];
        $post_id = wp_update_post( $post_data );
    } else {
        $post_id = wp_insert_post( $post_data );
    }
    
    if ( $post_id && ! is_wp_error( $post_id ) ) {
        // Update all meta
        foreach ( $args['data'] as $key => $value ) {
            update_post_meta( $post_id, $key, $value );
        }
        
        // Update sync metadata
        update_post_meta( $post_id, 'content_type', $args['content_type'] );
        update_post_meta( $post_id, 'item_id', $args['item_id'] );
        update_post_meta( $post_id, 'last_sync', current_time( 'mysql' ) );
        update_post_meta( $post_id, 'sync_status', 'synced' );
        
        // Store source course ID
        update_post_meta( $post_id, '_source_course_id', $args['item_id'] );
        
        return $post_id;
    }
    
    return false;
}
/**
 * Prepare comprehensive course data including all content
 */
function llms_content_prepare_comprehensive_course_data( $course ) {
    // Get instructors
    $instructors = $course->get_instructors();
    $instructor_names = [];
    
    foreach ( $instructors as $instructor ) {
        $user = get_userdata( $instructor['id'] );
        if ( $user ) {
            $instructor_names[] = $user->display_name;
        }
    }
    
    // Get course content
    $course_content = $course->get( 'content' );
    $course_excerpt = $course->get( 'excerpt' );
    
    // Get all sections with content
    $sections = $course->get_sections( 'sections' );
    $section_count = count( $sections );
    $section_titles = [];
    $all_section_content = [];
    
    foreach ( $sections as $section ) {
        $section_title = $section->get( 'order' ) . '. ' . $section->get( 'title' );
        $section_titles[] = $section_title;
        
        $section_content = $section->get( 'content' );
        if ( ! empty( $section_content ) ) {
            $all_section_content[] = "=== Section: " . $section_title . " ===\n" . strip_tags( $section_content );
        }
    }
    
    // Get all lessons with content
    $lessons = $course->get_lessons( 'lessons' );
    $lesson_titles = [];
    $all_lesson_content = [];
    $total_quizzes = 0;
    $total_assignments = 0;
    
    foreach ( $lessons as $lesson ) {
        $lesson_title = $lesson->get( 'title' );
        $lesson_titles[] = $lesson_title;
        
        // Get lesson content
        $lesson_content = $lesson->get( 'content' );
        if ( ! empty( $lesson_content ) ) {
            $all_lesson_content[] = "=== Lesson: " . $lesson_title . " ===\n" . strip_tags( $lesson_content );
        }
        
        // Check for quiz
        if ( $lesson->has_quiz() ) {
            $total_quizzes++;
            $quiz = $lesson->get_quiz();
            if ( $quiz ) {
                $quiz_content = $quiz->get( 'content' );
                if ( ! empty( $quiz_content ) ) {
                    $all_lesson_content[] = "--- Quiz: " . $quiz->get( 'title' ) . " ---\n" . strip_tags( $quiz_content );
                }
            }
        }
        
        // Check for assignment
        $assignment_id = $lesson->get( 'assignment' );
        if ( $assignment_id && get_post_type( $assignment_id ) === 'llms_assignment' ) {
            $total_assignments++;
            $assignment = get_post( $assignment_id );
            if ( $assignment && ! empty( $assignment->post_content ) ) {
                $all_lesson_content[] = "--- Assignment: " . $assignment->post_title . " ---\n" . strip_tags( $assignment->post_content );
            }
        }
    }
    
    // Get certificate info
    $has_certificate = false;
    $certificate_id = 0;
    $certificate_title = '';
    
    // Get engagements related to this course
    global $wpdb;
    $engagements = $wpdb->get_results( $wpdb->prepare(
        "SELECT * FROM {$wpdb->posts} 
         WHERE post_type = 'llms_engagement' 
         AND post_status = 'publish'
         AND ID IN (
            SELECT post_id FROM {$wpdb->postmeta} 
            WHERE meta_key = '_llms_engagement_trigger_post' 
            AND meta_value = %d
         )",
        $course->get( 'id' )
    ) );
    
    // Check for certificate engagements
    foreach ( $engagements as $engagement ) {
        $type = get_post_meta( $engagement->ID, '_llms_engagement_type', true );
        if ( 'certificate' === $type ) {
            $has_certificate = true;
            $cert_template_id = get_post_meta( $engagement->ID, '_llms_engagement', true );
            if ( $cert_template_id ) {
                $certificate_id = $cert_template_id;
                $cert_post = get_post( $certificate_id );
                if ( $cert_post ) {
                    $certificate_title = $cert_post->post_title;
                }
            }
            break; // Use first certificate found
        }
    }
    
    // Get engagement info (certificates, emails, achievements)
    $engagements = [];
    $engagement_posts = $wpdb->get_results( $wpdb->prepare(
        "SELECT p.*, pm.meta_value as engagement_type, pm2.meta_value as engagement_id
         FROM {$wpdb->posts} p
         LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_llms_engagement_type'
         LEFT JOIN {$wpdb->postmeta} pm2 ON p.ID = pm2.post_id AND pm2.meta_key = '_llms_engagement'
         WHERE p.post_type = 'llms_engagement' 
         AND p.post_status = 'publish'
         AND p.ID IN (
            SELECT post_id FROM {$wpdb->postmeta} 
            WHERE meta_key = '_llms_engagement_trigger_post' 
            AND meta_value = %d
         )",
        $course->get( 'id' )
    ) );
    
    foreach ( $engagement_posts as $eng ) {
        $type = $eng->engagement_type;
        $template_id = $eng->engagement_id;
        
        if ( $template_id ) {
            $template_post = get_post( $template_id );
            if ( $template_post ) {
                $type_label = '';
                switch ( $type ) {
                    case 'certificate':
                        $type_label = 'Certificate';
                        break;
                    case 'email':
                        $type_label = 'Email';
                        break;
                    case 'achievement':
                        $type_label = 'Achievement';
                        break;
                }
                
                if ( $type_label ) {
                    $engagements[] = $type_label . ': ' . $template_post->post_title;
                }
            }
        }
    }
    
    // Check if course is free using the correct method
    $is_free = 0;
    $is_free_meta = get_post_meta( $course->get( 'id' ), '_llms_is_free', true );
    if ( $is_free_meta === 'yes' ) {
        $is_free = 1;
    }
    
    // Get prerequisites info
    $has_prerequisite = $course->has_prerequisite( 'course' ) ? 1 : 0;
    $prerequisite_id = 0;
    if ( $has_prerequisite ) {
        $prereq = $course->get_prerequisite_id( 'course' );  // Using correct method
        if ( $prereq ) {
            $prerequisite_id = $prereq;
        }
    }
    
    // Get drip settings
    $drip_method = get_post_meta( $course->get( 'id' ), '_llms_drip_method', true );
    $drip_value = get_post_meta( $course->get( 'id' ), '_llms_days_before_available', true );
    
    return [
        // Basic course info
        'status'              => $course->get( 'status' ),
        'excerpt'             => $course_excerpt,
        'course_content'      => $course_content,
        
        // Course settings
        'course_duration'     => $course->get( 'length' ),
        'course_capacity'     => $course->get( 'capacity' ),
        'course_instructors'  => implode( "\n", $instructor_names ),
        'is_free'             => $is_free,
        
        // Structure info
        'section_count'       => $section_count,
        'section_list'        => implode( "\n", $section_titles ),
        'total_lessons'       => count( $lessons ),
        'lesson_list'         => implode( "\n", $lesson_titles ),
        'total_quizzes'       => $total_quizzes,
        'total_assignments'   => $total_assignments,
        
        // Certificate info
        'has_certificate'     => $has_certificate ? 1 : 0,
        'certificate_id'      => $certificate_id,
        'certificate_title'   => $certificate_title,
        
        // Engagements
        'engagements_list'    => implode( "\n", $engagements ),
        'engagements_count'   => count( $engagements ),
        
        // Prerequisites
        'has_prerequisite'    => $has_prerequisite,
        'prerequisite_id'     => $prerequisite_id,
        
        // Drip settings
        'drip_method'         => $drip_method ?: '',
        'drip_value'          => $drip_value ?: '',
        
        // All content aggregated
        'all_section_content' => implode( "\n\n", $all_section_content ),
        'all_lesson_content'  => implode( "\n\n", $all_lesson_content ),
        
        // Add these detail list placeholders (will be filled by detail population)
        'steps_details_list'        => '',
        'quizzes_details_list'      => '',
        'assignments_details_list'  => '',
        'sections_details_list'     => '',
        'certificates_details_list' => '',
        'engagements_details_list'  => '',
    ];
}

Comments

Add a Comment