VOOZH about

URL: https://deepwiki.com/Automattic/BuddyPress-VIP-Go/3.2-cover-image-handling

⇱ Cover Image Handling | Automattic/BuddyPress-VIP-Go | DeepWiki


Loading...
Menu

Cover Image Handling

Purpose and Scope

This document details how cover images (profile headers and group headers) are uploaded, stored, retrieved, and deleted in the BuddyPress VIP Go plugin. Cover images use a simplified storage model compared to avatars, storing only the original file URL in metadata and applying fixed transformation patterns on retrieval.

For information about avatar uploads and cropping, see Avatar Management. For details about dynamic image transformations and URL query parameters, see Dynamic Image Processing and URL Generation.

Overview

Cover images in BuddyPress VIP Go follow a streamlined approach:

  • Single file storage: Only the original uploaded image is stored in VIP File Hosting Service (FHS)
  • Minimal metadata: Only the file URL is stored in WordPress metadata (no crop coordinates)
  • Fixed crop pattern: All cover images use a consistent vertical crop (middle 25%) applied via query parameters
  • No user-controlled cropping: Unlike avatars, users cannot adjust cover image crop positions

This design reduces storage overhead and simplifies the upload workflow while leveraging VIP FHS's dynamic image transformation capabilities.

Sources: files.php277-324 README.md33-35

Cover Image Upload Process

Upload Flow


Sources: files.php562-649

Upload Function Implementation

The vip_handle_cover_image_upload() function intercepts the standard BuddyPress cover image upload process:

StepActionCode Reference
1. Switch to root blogEnsures metadata is stored on root blog in multisitefiles.php564-568
2. Include file functionsLoads wp_handle_upload() if neededfiles.php570-572
3. Upload fileProcesses $_FILES['file'] via WordPress corefiles.php576-586
4. Reset globalsRestores BuddyPress global state changed upstreamfiles.php589-596
5. Handle errorsReturns error array if upload failedfiles.php597-607
6. Store metadataSaves URL to user meta or group metafiles.php610-627
7. Fire actionTriggers {component}_cover_image_uploaded hookfiles.php629-635
8. Return successReturns array with URL and success statusfiles.php637-648

Sources: files.php562-649

Metadata Storage Logic


Sources: files.php610-635

Key Implementation Details

The cover image upload uses wp_handle_upload() with specific parameters:

$result = wp_handle_upload(
 $uploaded_file,
 array(
 'action' => 'wp_handle_upload', // Matches Core's action for VIP filters
 'test_form' => false, // Bypass form validation
 )
);

This ensures VIP File Hosting Service filters are properly applied during the upload process.

Sources: files.php579-585

Cover Image Retrieval and URL Generation

Retrieval Flow


Sources: files.php277-324

Fixed Crop Pattern

Cover images use a predefined crop pattern that differs from avatars:


The crop parameter 0,25,{width},{height} means:

  • X-offset: 0 (start at left edge)
  • Y-offset: 25% (start 25% down from top)
  • Width: Full component width
  • Height: Component-specified height

This creates a horizontally-centered, vertically middle-aligned crop.

Sources: files.php298-313

Component-Specific Dimensions

The plugin retrieves dimensions from BuddyPress based on the component:

ComponentObject DirectoryMetadata KeyDimension Source
User profilesmembersvipbp-user-coverbp_attachments_get_cover_image_dimensions('xprofile')
Groupsgroupsvipbp-group-coverbp_attachments_get_cover_image_dimensions('groups')

Sources: files.php287-298

Cover Image Deletion

Deletion Flow


Sources: files.php847-875

Deletion Implementation Details

The vipbp_delete_cover_image() function follows this process:


Sources: files.php847-875

URL Cleaning Process

Before deletion, the stored URL is processed:

// Remove query parameters (crop, resize, etc.)
$meta['url'] = strtok( $meta['url'], '?' );

// Convert full URL to relative path
$meta['url'] = str_replace( get_site_url() . '/', '', $meta['url'] );

// Delete using relative path
wp_delete_file( $meta['url'] );

This ensures the physical file is deleted from VIP FHS while avoiding issues with query parameters.

Sources: files.php866-867

Metadata Schema

Cover Image Metadata Structure

Cover images use a minimal metadata schema compared to avatars:

Metadata KeyApplied ToStructureStorage Location
vipbp-user-coverUser profilesarray('url' => string)User meta table (root blog)
vipbp-group-coverGroupsarray('url' => string)Group meta table (root blog)

Example metadata:


Sources: README.md33-35 files.php610-627

Comparison: Cover vs Avatar Metadata


Sources: README.md32-35 files.php610-627

Key Differences from Avatar Handling

Functional Comparison

AspectCover ImagesAvatars
Upload functionwp_handle_upload()wp_handle_sideload()
Filter hookbp_attachments_pre_cover_image_ajax_uploadbp_core_pre_avatar_handle_upload
Metadata storedURL onlyURL + crop coordinates + ui_width
User croppingNo (fixed pattern)Yes (user-adjustable)
Crop patternMiddle 25% verticallyUser-defined coordinates
Query parametersw, crop, stripw, crop, resize, strip

Sources: files.php33-37 files.php562-649 files.php336-464

Code Entity Mapping


Sources: files.php23-53 files.php277-875

Why wp_handle_upload() vs wp_handle_sideload()

Avatars use wp_handle_sideload() because BuddyPress has already validated the upload by the time the filter fires. Cover images use wp_handle_upload() to match WordPress Core's upload action, ensuring VIP File Service filters are properly applied.

// Cover image upload
$result = wp_handle_upload(
 $uploaded_file,
 array(
 'action' => 'wp_handle_upload', // Matches Core
 'test_form' => false,
 )
);

// Avatar upload 
$result = wp_handle_sideload(
 $uploaded_file,
 array(
 'action' => 'wp_handle_sideload', // After validation
 'test_form' => false,
 )
);

Sources: files.php579-585 files.php363-369

Related Operations

Multisite Blog Switching

All cover image operations switch to the root blog to centralize metadata storage:


This pattern appears in all three cover image functions:

Sources: files.php282-285 files.php564-568 files.php851-854

Component Action Hooks

After successful upload, the plugin fires component-specific action hooks:


This maintains compatibility with BuddyPress and BuddyBoss extensions that may listen for these events.

Sources: files.php629-635