This is a very common issue with programmatic BuddyPress updates. Why it is failing: Strict Folder Structure: BuddyPress doesn't just "know" an image exists. It looks for very specific filenames (like bp-full.jpg and bp-thumb.jpg) inside very specific folders (usually /wp-content/uploads/avatars/USER_ID/). Caching: BuddyPress caches avatar URLs aggressively. Even if the file is uploaded, BP might still be serving the old cached URL. The "Silent" Error: Your AJAX returns "success" because the file did upload to your /tilpimages/ folder, but the logic to copy it to the BuddyPress folder likely failed silently. Here is the re-written, robust PHP handler for functions.php. What this new code does: Saves to your custom /tilpimages/ folder (as requested). Brute Forces BuddyPress: It manually creates the required BuddyPress folders, resizes the images to the exact dimensions BP expects, and names them bp-full.jpg and bp-thumb.jpg. Updates the Database: It forces an update to the _bp_cover_image meta key. Clears Cache: It runs commands to tell WordPress "forget the old image." Step 1: Update functions.php Delete the previous tilp_handle_image_upload and tilp_set_buddypress_... functions and replace them with this strict version: PHP add_action( 'wp_ajax_tilp_upload_image', 'tilp_handle_image_upload' ); function tilp_handle_image_upload() { check_ajax_referer( 'tilp_upload_nonce', 'security' ); // 1. Basic Validation if ( ! isset( $_FILES['image_file'] ) ) { wp_send_json_error( 'No file uploaded' ); } $user_id = get_current_user_id(); $type = sanitize_text_field( $_POST['image_type'] ); // 'avatar' or 'cover' $file = $_FILES['image_file']; require_once( ABSPATH . 'wp-admin/includes/image.php' ); require_once( ABSPATH . 'wp-admin/includes/file.php' ); require_once( ABSPATH . 'wp-admin/includes/media.php' ); // 2. Save to your custom /tilpimages/ folder first (Source of Truth) $upload_dir = wp_upload_dir(); $custom_dir_name = 'tilpimages'; $custom_path = $upload_dir['basedir'] . '/' . $custom_dir_name; $custom_url = $upload_dir['baseurl'] . '/' . $custom_dir_name; if ( ! file_exists( $custom_path ) ) { wp_mkdir_p( $custom_path ); } $ext = pathinfo( $file['name'], PATHINFO_EXTENSION ); $timestamp = time(); $new_filename = $timestamp . '_' . $user_id . '.' . $ext; $master_file_path = $custom_path . '/' . $new_filename; $master_file_url = $custom_url . '/' . $new_filename; // Move uploaded file to /tilpimages/ if ( ! move_uploaded_file( $file['tmp_name'], $master_file_path ) ) { wp_send_json_error( 'Failed to save to tilpimages folder.' ); } // Compress if > 5MB if ( filesize( $master_file_path ) > 5 * 1024 * 1024 ) { $editor = wp_get_image_editor( $master_file_path ); if ( ! is_wp_error( $editor ) ) { $editor->set_quality( 60 ); $editor->save( $master_file_path ); } } // 3. PROCESS FOR BUDDYPRESS $bp_success = false; if ( $type === 'avatar' ) { $bp_success = tilp_force_bp_avatar( $master_file_path, $user_id ); } elseif ( $type === 'cover' ) { $bp_success = tilp_force_bp_cover( $master_file_path, $user_id, $master_file_url ); } // 4. Return Result if ( $bp_success ) { // Clear User Cache to ensure UI updates immediately clean_user_cache( $user_id ); wp_cache_delete( $user_id, 'bp_last_activity' ); wp_send_json_success( array( 'url' => $master_file_url, 'message' => 'Image updated successfully' )); } else { wp_send_json_error( 'Saved to tilpimages, but failed to update BuddyPress profile.' ); } } /** * STRICT AVATAR HANDLER * Manually places bp-full.jpg and bp-thumb.jpg in the avatar folder. */ function tilp_force_bp_avatar( $source_file, $user_id ) { // Define standard BP Avatar path: /wp-content/uploads/avatars/USER_ID/ $bp_upload_path = bp_core_avatar_upload_path(); $user_avatar_dir = $bp_upload_path . '/' . $user_id; // Delete existing avatars first to prevent conflicts if ( file_exists( $user_avatar_dir ) ) { array_map( 'unlink', glob( "$user_avatar_dir/*.*" ) ); } else { wp_mkdir_p( $user_avatar_dir ); } $editor = wp_get_image_editor( $source_file ); if ( is_wp_error( $editor ) ) return false; // 1. Create Full Size (bp-full.jpg) - Usually 150x150 or defined by theme $editor->resize( BP_AVATAR_FULL_WIDTH, BP_AVATAR_FULL_HEIGHT, true ); $full_save = $editor->save( $user_avatar_dir . '/bp-full.jpg' ); // 2. Create Thumb Size (bp-thumb.jpg) $editor->resize( BP_AVATAR_THUMB_WIDTH, BP_AVATAR_THUMB_HEIGHT, true ); $thumb_save = $editor->save( $user_avatar_dir . '/bp-thumb.jpg' ); if ( ! is_wp_error( $full_save ) ) { return true; } return false; } /** * STRICT COVER IMAGE HANDLER * Manually places the image in the BP cover-image folder and updates User Meta. */ function tilp_force_bp_cover( $source_file, $user_id, $public_url ) { // 1. Determine Cover Directory: /wp-content/uploads/buddypress/members/USER_ID/cover-image/ $bp = buddypress(); $upload_dir = bp_upload_dir(); $cover_dir = $upload_dir['basedir'] . '/members/' . $user_id . '/cover-image'; if ( ! file_exists( $cover_dir ) ) { wp_mkdir_p( $cover_dir ); } // 2. Define the new filename (BuddyPress usually generates a random name) $filename = wp_basename( $source_file ); $destination = $cover_dir . '/' . $filename; // 3. Copy the file if ( ! copy( $source_file, $destination ) ) { return false; } // 4. VITAL: Update the User Meta so BP knows the file is there // This is often why the image doesn't show up—the physical file exists, but the DB doesn't know. update_user_meta( $user_id, 'bp_cover_image', array( 'file' => $filename, 'align' => 'top' ) ); // 5. Update Custom Profile Manager meta just in case your theme uses a custom key // Since you use Tilp_Profile_Manager, it might look for this: update_user_meta( $user_id, 'tilp_cover_image', $public_url ); return true; } Step 2: Update the JavaScript (Template File) There is a browser caching issue where the browser sees the old image URL and doesn't bother re-fetching it, even if the file changed. We need to "bust" the cache aggressively in the JavaScript. Find this section in your template script and update the success block: JavaScript success: function(response) { if(response.success) { showStatus('Image updated successfully!', 'success'); // Cache Buster: Add a random number to the end of the URL var uniqueURL = response.data.url + '?t=' + new Date().getTime(); // Update the Preview immediately $(previewID).css('background-image', 'url(' + uniqueURL + ')'); // ALSO: Try to update any other images on the page (like the sidebar avatar) // This targets the standard BP avatar classes if(type === 'avatar') { $('.avatar, .ut-prof-avatar').attr('src', uniqueURL); $('.ut-set-user-label img').attr('src', uniqueURL); // Update sidebar if it has img } } else { showStatus('Error: ' + response.data, 'error'); } }, Step 3: Debugging (If it still fails) If this still doesn't work, we need to see the server error log. Open your wp-config.php file via FTP/File Manager. Change define( 'WP_DEBUG', false ); to: PHP define( 'WP_DEBUG', true ); define( 'WP_DEBUG_LOG', true ); define( 'WP_DEBUG_DISPLAY', false ); Add this line inside the tilp_handle_image_upload function in functions.php right after $file = $_FILES['image_file'];: PHP error_log( 'Starting upload for User ' . $user_id . ' Type: ' . $type ); Try the upload again. Check the file /wp-content/debug.log. It will tell you if there are "Permission Denied" errors when trying to write to the folders. Why the Tilp_Profile_Manager matters In your template, you have: $cover_image = $profile_manager->get_cover_image($user_id);. If the class Tilp_Profile_Manager is coded to strictly look for a custom meta key (and ignores standard BuddyPress), standard BP updates won't work. I added Step 4 in the tilp_force_bp_cover function above to attempt to fix this: PHP update_user_meta( $user_id, 'tilp_cover_image', $public_url ); If your specific theme uses a different meta key (like _listing_cover_image or similar), you need to find that key name in your database (table wp_usermeta) and update the code to match it.
Warning: Cannot modify header information - headers already sent by (output started at /var/www/vhosts/tilp.me/httpdocs/wp-content/themes/tilp-theme/inc/class-profilesettings.php:1) in /var/www/vhosts/tilp.me/httpdocs/wp-includes/sitemaps/class-wp-sitemaps-renderer.php on line 126
https://tilp.me/wp-sitemap-posts-post-1.xmlhttps://tilp.me/wp-sitemap-posts-page-1.xmlhttps://tilp.me/wp-sitemap-taxonomies-category-1.xmlhttps://tilp.me/wp-sitemap-users-1.xml