Created
June 5, 2023 17:46
-
-
Save bookchiq/2a8f85efe6fd46a7df33b2dba899fd00 to your computer and use it in GitHub Desktop.
Update a BuddyPress/BuddyBoss avatar from an external URL
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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