VOOZH about

URL: https://deepwiki.com/Automattic/BuddyPress-VIP-Go/2.2-core-integration-layer-(files.php)

⇱ Core Integration Layer (files.php) | Automattic/BuddyPress-VIP-Go | DeepWiki


Loading...
Menu

Core Integration Layer (files.php)

Purpose and Scope

The files.php module is the central integration layer that redirects all BuddyPress media operations from the local filesystem to WordPress VIP Go's file hosting infrastructure. It intercepts 11+ BuddyPress hooks to handle uploads, crops, retrievals, and deletions for avatars, cover images, and videos.

This document covers the hook interception architecture, media operation workflows, and metadata storage patterns implemented in this file. For information about the plugin's initialization and environment detection, see Plugin Initialization and Environment Detection. For details on the metadata schema structure, see Metadata Storage Architecture.

Sources: files.php1-902


Hook Registration Architecture

The files.php module registers hooks at three distinct phases to ensure proper integration with BuddyPress:

  1. Early Filters (file load time): Prevent filesystem operations before BuddyPress initializes
  2. Core Hooks (bp_init action): Register primary interception filters
  3. Post-Save Actions: Cache management after media operations

Critical Early Filters

Two filters are registered at file load time (before bp_init) to prevent BuddyPress from accessing the filesystem:

Filter HookHandlerPurposeLine
bp_disable_avatar_history__return_trueDisables BP 10.0+ avatar history feature that requires directory listing12
bp_core_avatar_folder_dir__return_empty_stringReturns empty string to prevent bp_core_fetch_avatar() from scanning filesystem16

The bp_core_avatar_folder_dir filter is particularly critical—it runs during bp_setup_title() at bp_init priority 8, so it must be registered earlier to prevent filesystem iteration before VIP integration is fully initialized.

Sources: files.php11-16


Avatar Upload Workflow

Avatar uploads follow a two-stage process: (1) upload to VIP storage via WordPress core APIs, and (2) store metadata with crop coordinates for later retrieval.


Key Implementation Details

File Storage: The function uses wp_handle_sideload() instead of wp_handle_upload() (line 357) for consistency with webcam captures and because BuddyPress has already validated the upload upstream. The test_form parameter is set to false to bypass WordPress's form validation.

Image Width Clamping: Lines 378-386 implement logic to prevent upscaling issues when avatars are uploaded from narrow displays (e.g., mobile devices). The ui_width value is stored in metadata and later applied as a w query parameter.

Metadata Structure: The initial metadata stored includes placeholder crop coordinates defaulting to the full image dimensions:

{
 'crop_w': bp_core_avatar_full_width(), // e.g., 150
 'crop_h': bp_core_avatar_full_height(), // e.g., 150
 'crop_x': 0,
 'crop_y': 0,
 'ui_width': <calculated_width>,
 'url': <vip_file_url>
}

Default Group Avatar Handling: When object_id is 0 (lines 420-421), the avatar is stored in wp_options as vipbp-default-group-avatar instead of wp_bp_groups_groupmeta, since there is no group ID 0.

Sources: files.php330-458


Webcam Capture Upload

Webcam captures follow a similar but memory-optimized workflow using wp_upload_bits() instead of wp_handle_sideload().


Memory Efficiency: Line 489 immediately calls unset($data) after uploading to free the base64-decoded image data from memory, which can be several megabytes for high-resolution captures.

Filename Generation: Webcam captures use a predictable naming pattern: webcam-{item_id}-{random}.png where the random component is a 6-character password generated via wp_generate_password(6, false) (line 485).

Sources: files.php470-539


Cover Image Upload

Cover image uploads handle both user and group covers, with simpler metadata (only storing the URL) since covers use standardized cropping dimensions.


Key Differences from Avatar Upload:

  1. Handler Function: Uses wp_handle_upload() (line 573) instead of wp_handle_sideload(), with action parameter set to 'wp_handle_upload' to ensure VIP file service filters are applied.

  2. Simpler Metadata: Only stores {url} (lines 608-609, 617-618) since cover images don't support custom cropping—they use standardized dimensions from bp_attachments_get_cover_image_dimensions().

  3. Global Reset: Lines 583-589 reset BuddyPress globals that were modified by bp_attachments_cover_image_ajax_upload() upstream, passed via the $needs_reset parameter.

  4. Return Value: Unlike avatar functions that return false to shortcircuit, this returns an array with result, feedback_code, name, and url (lines 631-636).

Sources: files.php556-643


Avatar Crop Handling

Cropping operations store only coordinate adjustments in metadata—no new physical files are created. Dynamic cropping occurs at image retrieval time via URL parameters.


Validation Logic: Lines 692-697 and 711-716 implement a critical validation: if the metadata lacks a url field (indicating a failed upload), the function returns false without updating crop coordinates. This prevents storing crop data for non-existent images.

Metadata Preservation: The function uses wp_parse_args($cropping_meta, $meta) (lines 699, 718) to merge new crop coordinates with existing metadata, preserving the url and ui_width fields from the original upload.

Sources: files.php673-733


Avatar URL Generation and Dynamic Processing

Avatar retrieval generates URLs with Photon-like query parameters that instruct VIP's file service to perform on-demand cropping and resizing.


URL Parameter Construction

The vipbp_filter_avatar_urls() helper function (lines 142-250) constructs query parameters that implement dynamic image processing:

ParameterPurposeExample ValueCode Reference
wClamp image width (prevent upscaling from mobile)320, 450lines 217, 236-238
cropCrop coordinates in pixels10px,20px,150px,150pxlines 220-226
resizeTarget dimensions for final image50,50 (thumb) or 150,150 (full)line 229
stripRemove EXIF/IPTC metadatainfoline 232

Example Generated URL:

https://vip-uploads.example.com/2024/01/avatar.jpg
 ?w=450
 &crop=10px,20px,150px,150px
 &resize=150,150
 &strip=info

Gravatar Fallback

When no metadata exists (line 157), the function generates a standard Gravatar URL (lines 159-207) using:

  • Email hash: md5(strtolower($params['email']))
  • Default type: $bp->grav_default->{$params['object']} or 'wavatar'
  • Size: $params['width']
  • Force default: $params['force_default']
  • Rating: $params['rating']

For groups/blogs without email, a synthetic email is generated: {item_id}-{object}@{root_domain} (line 171).

Sources: files.php64-83 files.php100-130 files.php142-250


Cover Image URL Generation

Cover images use a simplified URL generation pattern with standardized cropping dimensions.


Standardized Cropping: Unlike avatars which use user-specified crop coordinates, cover images apply a fixed crop pattern (line 301):

crop=0,25,{width}px,{height}px

This crops from the left edge (0), starting 25% down from the top (25), capturing the full width and height specified by bp_attachments_get_cover_image_dimensions().

No Resize Parameter: Cover images omit the resize parameter since they're displayed at their actual dimensions determined by the theme's cover image settings.

Sources: files.php271-318


Deletion Operations

Deletion operations follow a two-step pattern: (1) retrieve metadata to get the file URL, (2) delete metadata from database, (3) delete physical file from VIP storage.

Avatar Deletion


URL Cleaning: Line 819 performs two critical transformations before deletion:

  1. strtok($meta['url'], '?') - Removes all query parameters (e.g., ?w=450&crop=...)
  2. str_replace(get_site_url() . '/', '', ...) - Converts absolute URL to relative path

This ensures wp_delete_file() receives a path relative to the uploads directory (e.g., 2024/01/avatar.jpg instead of https://site.com/wp-content/uploads/2024/01/avatar.jpg?w=450).

Sources: files.php755-830

Cover Image Deletion


Cover image deletion follows the same pattern as avatar deletion but is simpler since there's no default cover image special case.

Sources: files.php841-869


Video Upload and Cache Management

Video handling includes temporary file cleanup and cache flushing after video moves.

Temporary Directory Override


Purpose: BuddyPress's default bp_core_remove_temp_directory() uses PHP's rmdir() which is incompatible with VIP's filesystem abstraction. This override (lines 880-891) uses wp_delete_file() instead, which works with VIP's WP_Filesystem implementation.

Targeted Override: The function only overrides when the specific file exists (line 883), returning false otherwise to allow BuddyPress's default directory cleanup logic to run.

Sources: files.php880-891

Video Move Cache Flush


Cache Invalidation: When a video is moved to an album, line 900 calls bp_core_reset_incrementor('bp_media') to invalidate BuddyPress's media cache group. This ensures cached media queries reflect the new album association.

Hook Priority: Registered at priority 99 (line 45) to ensure it runs after all other video processing is complete.

Sources: files.php899-901


Multisite Blog Switching Pattern

Every function that accesses metadata implements a consistent blog-switching pattern to ensure operations occur on the root blog in multisite installations.


Implementation Across Functions

FunctionBlog Switch LinesRestore LinesMetadata Access Type
vipbp_filter_user_avatar_urls67-7078-80Read user meta
vipbp_filter_group_avatar_urls103-106125-127Read group meta / options
vipbp_filter_avatar_urls146-149203-205, 245-247Read (delegated)
vipbp_filter_get_cover_image276-279313-315Read user/group meta
vipbp_handle_avatar_upload333-336453-455Write user/group meta
vipbp_handle_avatar_capture478-481534-536Write user meta
vip_handle_cover_image_upload559-562638-640Write user/group meta
vipbp_handle_avatar_crop683-686728-730Update user/group meta
vipbp_delete_existing_avatar759-762825-827Delete user/group meta
vipbp_delete_cover_image845-848864-866Delete user/group meta

Rationale: BuddyPress stores all media metadata on the root blog (blog ID 1) in multisite networks, regardless of which subsite triggered the operation. The blog-switching pattern ensures metadata is read from and written to the correct database tables.

Performance Consideration: The switched flag prevents redundant restore_current_blog() calls when already on the root blog, avoiding unnecessary overhead.

Sources: Multiple functions throughout files.php1-902


Function Reference Table

Function NameHook/FilterPurposeReturn ValueLines
vipbp_filter_user_avatar_urlsbp_core_default_avatar_userGenerate avatar URLs for usersString (URL)64-83
vipbp_filter_group_avatar_urlsbp_core_default_avatar_groupGenerate avatar URLs for groupsString (URL)100-130
vipbp_filter_avatar_urlsHelper functionBuild avatar URLs with Photon paramsString (URL)142-250
vipbp_filter_get_cover_imagebp_attachments_pre_get_attachmentGenerate cover image URLsString (URL) or false271-318
vipbp_handle_avatar_uploadbp_core_pre_avatar_handle_uploadUpload avatars via wp_handle_sideloadfalse (shortcircuit)330-458
vipbp_handle_avatar_capturebp_avatar_pre_handle_captureUpload webcam captures via wp_upload_bitsfalse (shortcircuit)470-539
vip_handle_cover_image_uploadbp_attachments_pre_cover_image_ajax_uploadUpload cover images via wp_handle_uploadArray {result, message, type}556-643
vipbp_handle_avatar_cropbp_core_pre_avatar_handle_cropStore crop coordinates in metadatafalse (shortcircuit)673-733
vipbp_delete_existing_avatarbp_core_pre_delete_existing_avatarDelete avatar files and metadatafalse (shortcircuit)755-830
vipbp_delete_cover_imagebp_attachments_pre_delete_fileDelete cover image files and metadatafalse (shortcircuit)841-869
vipbp_override_remove_temp_directorybp_core_pre_remove_temp_directoryUse wp_delete_file for temp cleanuptrue (override) or false (continue)880-891
vipbp_flush_cache_after_video_movebp_video_after_saveInvalidate media cache after video movevoid899-901

Shortcircuit Pattern: Most functions return false to indicate they've handled the operation, preventing BuddyPress from executing its default filesystem-based implementation. This is the standard WordPress pre-filter pattern for overriding default behavior.

Sources: files.php1-902