FROM " . self::TABLE . " WHERE user_id = %d AND completed = 0 AND last_watched IS NOT NULL ORDER BY last_watched DESC LIMIT %d", $user_id, $limit ), ARRAY_A ); } public static function get_completed_files( $user_id, $product_id = null ) { global $wpdb; if ( $product_id ) { return $wpdb->get_col( $wpdb->prepare( "SELECT drive_file_id FROM " . self::TABLE . " WHERE user_id = %d AND product_id = %d AND completed = 1", $user_id, $product_id ) ); } return $wpdb->get_col( $wpdb->prepare( "SELECT drive_file_id FROM " . self::TABLE . " WHERE user_id = %d AND completed = 1", $user_id ) ); } /** * Pega map (drive_file_id => completed/in-progress) pra um curso */ public static function get_progress_map( $user_id, $product_id ) { global $wpdb; $rows = $wpdb->get_results( $wpdb->prepare( "SELECT drive_file_id, completed, last_watched FROM " . self::TABLE . " WHERE user_id = %d AND product_id = %d", $user_id, $product_id ), ARRAY_A ); $map = array(); foreach ( $rows as $r ) { $map[ $r['drive_file_id'] ] = array( 'completed' => (int) $r['completed'], 'last_watched' => $r['last_watched'], ); } return $map; } public static function get_progress_percent( $user_id, $product_id ) { global $wpdb; $total = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM " . CR_Drive_Sync::TABLE_FILES . " WHERE product_id = %d AND mime_type LIKE 'video/%'", $product_id ) ); if ( $total === 0 ) return 0; $completed = (int) $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM " . self::TABLE . " WHERE user_id = %d AND product_id = %d AND completed = 1", $user_id, $product_id ) ); return round( ( $completed / $total ) * 100 ); } /** * Estima duração em segundos baseado no tamanho do arquivo */ public static function estimate_duration( $file_size_bytes ) { if ( ! $file_size_bytes || $file_size_bytes < 1 ) return null; return (int) ( $file_size_bytes / self::ESTIMATED_BYTES_PER_SECOND ); } // ═══════════════════════════════════════════════ // AJAX // ═══════════════════════════════════════════════ public static function ajax_track_open() { if ( ! check_ajax_referer( 'cr_progress_nonce', 'nonce', false ) ) wp_send_json_error(); if ( ! is_user_logged_in() ) wp_send_json_error(); $user_id = get_current_user_id(); $drive_file_id = sanitize_text_field( $_POST['drive_file_id'] ?? '' ); if ( ! $drive_file_id ) wp_send_json_error(); // Pegar metadata do arquivo do banco pra preencher global $wpdb; $file = null; if ( class_exists( 'CR_Drive_Sync' ) ) { $file = $wpdb->get_row( $wpdb->prepare( "SELECT product_id, file_name, drive_folder_id, folder_path, mime_type, file_size FROM " . CR_Drive_Sync::TABLE_FILES . " WHERE drive_file_id = %s", $drive_file_id ), ARRAY_A ); } $extra = array(); if ( $file ) { $extra = array( 'product_id' => $file['product_id'], 'file_name' => $file['file_name'], 'folder_id' => $file['drive_folder_id'], 'folder_path' => $file['folder_path'], 'mime_type' => $file['mime_type'], 'duration_seconds' => self::estimate_duration( $file['file_size'] ), ); } self::track_open( $user_id, $drive_file_id, $extra ); wp_send_json_success(); } public static function ajax_track_close() { if ( ! check_ajax_referer( 'cr_progress_nonce', 'nonce', false ) ) wp_send_json_error(); if ( ! is_user_logged_in() ) wp_send_json_error(); $user_id = get_current_user_id(); $drive_file_id = sanitize_text_field( $_POST['drive_file_id'] ?? '' ); $seconds_spent = (int) ( $_POST['seconds_spent'] ?? 0 ); if ( ! $drive_file_id ) wp_send_json_error(); $result = self::track_close( $user_id, $drive_file_id, $seconds_spent ); wp_send_json_success( $result ); } public static function ajax_mark_completed() { if ( ! check_ajax_referer( 'cr_progress_nonce', 'nonce', false ) ) wp_send_json_error(); if ( ! is_user_logged_in() ) wp_send_json_error(); $user_id = get_current_user_id(); $drive_file_id = sanitize_text_field( $_POST['drive_file_id'] ?? '' ); if ( ! $drive_file_id ) wp_send_json_error(); // Pegar metadata se o registro não existir ainda global $wpdb; $exists = $wpdb->get_var( $wpdb->prepare( "SELECT 1 FROM " . self::TABLE . " WHERE user_id = %d AND drive_file_id = %s", $user_id, $drive_file_id ) ); if ( ! $exists ) { // Cria registro vindo do banco de arquivos $file = $wpdb->get_row( $wpdb->prepare( "SELECT product_id, file_name, drive_folder_id, folder_path, mime_type, file_size FROM " . CR_Drive_Sync::TABLE_FILES . " WHERE drive_file_id = %s", $drive_file_id ), ARRAY_A ); if ( $file ) { self::track_open( $user_id, $drive_file_id, array( 'product_id' => $file['product_id'], 'file_name' => $file['file_name'], 'folder_id' => $file['drive_folder_id'], 'folder_path' => $file['folder_path'], 'mime_type' => $file['mime_type'], 'duration_seconds' => self::estimate_duration( $file['file_size'] ), ) ); } } self::mark_completed( $user_id, $drive_file_id, 1 ); wp_send_json_success(); } public static function ajax_mark_uncompleted() { if ( ! check_ajax_referer( 'cr_progress_nonce', 'nonce', false ) ) wp_send_json_error(); if ( ! is_user_logged_in() ) wp_send_json_error(); $user_id = get_current_user_id(); $drive_file_id = sanitize_text_field( $_POST['drive_file_id'] ?? '' ); if ( ! $drive_file_id ) wp_send_json_error(); self::mark_completed( $user_id, $drive_file_id, 0 ); wp_send_json_success(); } } CR_Progress::init(); endif;
