Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save bookchiq/2a8f85efe6fd46a7df33b2dba899fd00 to your computer and use it in GitHub Desktop.
Save bookchiq/2a8f85efe6fd46a7df33b2dba899fd00 to your computer and use it in GitHub Desktop.
Update a BuddyPress/BuddyBoss avatar from an external URL
<?php
/**
* Updates the avatar of a user based on the user's ID.
*
* This function downloads an image from an external URL and saves it
* as the user's avatar. If the image is not square, it crops it to a
* square shape before saving.
*
* @since 1.0.0
* @access public
* @static
*
* @global WP_Filesystem $wp_filesystem WordPress filesystem API.
*
* @param int $user_id The ID of the user whose avatar is to be updated.
* @return mixed WP_Error object on failure, or string on success.
*/
function update_buddypress_avatar_from_external_url( $user_id ) {
$user = get_user_by( 'id', $user_id );
if ( empty( $user ) ) {
return new WP_Error( 'invalid_user', 'Invalid user ID' );
}
$external_avatar_url = 'https://example.com/avatar.jpg'; // Replace with your external avatar URL.
// Fetch the last updated avatar URL.
$last_avatar_url = get_user_meta( $user_id, 'last_avatar_url', true );
$existing_avatar_path = get_user_meta( $user_id, 'existing_avatar_path', true );
// Check if the avatar URL has changed.
if ( $external_avatar_url === $last_avatar_url ) {
// Fetch the size of the existing avatar on your server.
$existing_avatar_size = filesize( $existing_avatar_path );
// Fetch the header from the external URL (doesn't download the body).
$response = wp_remote_head(
$external_avatar_url,
array(
'timeout' => 30,
)
);
// Check for an error.
if ( is_wp_error( $response ) ) {
return new WP_Error( 'retrieving_error', 'Error when retrieving avatar file' );
}
// Fetch the size of the image from the external URL.
$new_avatar_size = (int) $response['headers']['content-length'];
// If the sizes match, there's no need to update the avatar.
if ( $existing_avatar_size === $new_avatar_size ) {
return;
}
}
// Download the image to our server.
$response = wp_remote_get(
$external_avatar_url,
array(
'timeout' => 30,
)
);
if ( is_wp_error( $response ) ) {
return new WP_Error( 'retrieving_error', 'Error when retrieving avatar file' );
}
$image_data = wp_remote_retrieve_body( $response );
// Get the upload directory for avatars.
$upload_dir = bp_core_avatar_upload_path() . '/avatars/' . $user_id;
// If the directory doesn't exist, create it.
if ( ! file_exists( $upload_dir ) ) {
if ( ! mkdir( $upload_dir, 0755, true ) ) {
return new WP_Error( 'directory_creation_error', 'Failed to create directory.' );
}
}
// Get the image type and corresponding extension.
$image_type = exif_imagetype( $external_avatar_url );
$extension = image_type_to_extension( $image_type, false );
// Check if extension is valid.
if ( ! in_array( $extension, array( 'jpg', 'jpeg', 'png', 'gif', 'webp' ), true ) ) {
return new WP_Error( 'invalid_file_extension', 'Invalid file extension' );
}
// Construct the avatar file names.
$avatar_original = time() . '-bporiginal.' . $extension;
$avatar_full = time() . '-bpfull.' . $extension;
$avatar_thumb = time() . '-bpthumb.' . $extension;
// Remove existing avatar files to avoid conflicts.
$existing_files = glob( $upload_dir . '/*-bp{full,thumb,original}.*', GLOB_BRACE );
foreach ( $existing_files as $existing_file ) {
if ( ! @unlink( $existing_file ) ) {
return new WP_Error( 'unlink_error', 'Failed to delete existing file.' );
}
}
// Clear the avatar cache so BuddyPress recognizes the new avatars.
bp_core_delete_existing_avatar( array( 'item_id' => $user_id ) );
// Create the full path to the avatar files.
$filename_original = $upload_dir . '/' . $avatar_original;
$filename_full = $upload_dir . '/' . $avatar_full;
$filename_thumb = $upload_dir . '/' . $avatar_thumb;
// Initialize WP_Filesystem API.
global $wp_filesystem;
if ( ! $wp_filesystem ) {
if ( ! defined( 'FS_METHOD' ) ) {
define( 'FS_METHOD', 'direct' );
}
require_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
}
// Use WP_Filesystem to write file.
if ( ! $wp_filesystem->put_contents( $filename_original, $image_data ) ) {
return new WP_Error( 'writing_error', 'Error when writing file' );
}
// Resize the avatars to match BuddyPress's sizing.
// Include the image manipulation library.
require_once ABSPATH . 'wp-admin/includes/image.php';
// Load the image.
$image = wp_get_image_editor( $filename_original );
if ( is_wp_error( $image ) ) {
return $image; // Return the WP_Error object.
}
// Get the image size.
$size = $image->get_size();
// Calculate new crop dimensions.
$crop_width = min( $size['width'], $size['height'] );
$crop_height = $crop_width;
// Calculate the x and y coordinates for cropping from the center.
$x = max( 0, ( $size['width'] - $crop_width ) / 2 );
$y = max( 0, ( $size['height'] - $crop_height ) / 2 );
// Crop the image.
$image->crop( $x, $y, $crop_width, $crop_height, $crop_width, $crop_height );
// Save the image file.
$new_image_path = $image->save( $filename_full );
// Create a new instance of the image for thumbnail.
$thumbnail = wp_get_image_editor( $filename_full );
if ( is_wp_error( $thumbnail ) ) {
return $thumbnail; // Return the WP_Error object.
}
// Resize the thumbnail to 300x300 pixels.
$thumbnail->resize( 300, 300, true );
// Save the thumbnail with the appropriate filename.
$thumbnail->save( $filename_thumb );
if ( ! empty( $new_image_path['path'] ) ) {
// After updating, save the user meta for next time.
update_user_meta( $user_id, 'last_avatar_url', $external_avatar_url );
update_user_meta( $user_id, 'existing_avatar_path', $filename_original );
return $new_image_path['path'];
} else {
return new WP_Error( 'unknown_error', 'Unknown error' );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment