Skip to content

Host/Domain change support added for local avatar url #216

New issue

Have a question about this project? Sign up for a free account to open an issue and contact its maintainers and the community.

By clicking “Sign up for ”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on ? Sign in to your account

Merged
merged 16 commits into from
Sep 25, 2023
Merged
2 changes: 2 additions & 0 deletions .gitignore
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,3 +39,5 @@ tests/cypress/screenshots
tests/cypress/videos
tests/cypress/downloads
tests/cypress/reports

.phpunit.result.cache
140 changes: 76 additions & 64 deletions includes/class-simple-local-avatars.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -65,9 +65,9 @@ class Simple_Local_Avatars {
public function __construct() {
$this->add_hooks();

$this->options = (array) get_option( 'simple_local_avatars' );
$this->user_key = 'simple_local_avatar';
$this->rating_key = 'simple_local_avatar_rating';
$this->options = (array) get_option( 'simple_local_avatars' );
$this->user_key = 'simple_local_avatar';
$this->rating_key = 'simple_local_avatar_rating';

if (
! $this->is_avatar_shared() // Are we sharing avatars?
Expand DownExpand Up@@ -136,18 +136,26 @@ public function add_hooks() {
}

if ( 'profile.php' === $pagenow ) {
add_filter( 'media_view_strings', function ( $strings ) {
$strings['skipCropping'] = esc_html__( 'Default Crop', 'simple-local-avatars' );

return $strings;
}, 10, 1 );
add_filter(
'media_view_strings',
function ( $strings ) {
$strings['skipCropping'] = esc_html__( 'Default Crop', 'simple-local-avatars' );

return $strings;
},
10,
1
);
}

// Fix: An error occurred cropping the image (https://.com/10up/simple-local-avatars/issues/141).
if ( isset( $_POST['action'] ) && 'crop-image' === $_POST['action'] && is_admin() && wp_doing_ajax() ) {
add_action( 'plugins_loaded', function () {
remove_all_actions( 'setup_theme' );
} );
add_action(
'plugins_loaded',
function () {
remove_all_actions( 'setup_theme' );
}
);
}
}

Expand DownExpand Up@@ -330,14 +338,21 @@ public function get_user_id( $id_or_email ) {
*/
public function get_simple_local_avatar_url( $id_or_email, $size ) {
$user_id = $this->get_user_id( $id_or_email );
$size = (int) $size;

if ( empty( $user_id ) ) {
return '';
}

// Fetch local avatar from meta and make sure it's properly set.
$local_avatars = get_user_meta( $user_id, $this->user_key, true );
if ( empty( $local_avatars['full'] ) ) {

// Return avatar if exists.
if ( is_array( $local_avatars ) && array_key_exists( $size, $local_avatars ) && ( strpos( $local_avatars[ $size ], content_url() ) === 0 ) ) {
return esc_url( $local_avatars[ $size ] );
}

// Fetch local avatar from meta and make sure it's properly set.
if ( empty( $local_avatars['media_id'] ) ) {
return '';
}

Expand All@@ -354,69 +369,66 @@ public function get_simple_local_avatar_url( $id_or_email, $size ) {
}

// handle "real" media
if ( ! empty( $local_avatars['media_id'] ) ) {
// If using shared avatars, make sure we validate the URL on the main site.
if ( $this->is_avatar_shared() ) {
$origin_blog_id = isset( $local_avatars['blog_id'] ) && ! empty( $local_avatars['blog_id'] ) ? $local_avatars['blog_id'] : get_main_site_id();
switch_to_blog( $origin_blog_id );
}
// If using shared avatars, make sure we validate the URL on the main site.
if ( $this->is_avatar_shared() ) {
$origin_blog_id = ! empty( $local_avatars['blog_id'] ) ? $local_avatars['blog_id'] : get_main_site_id();
switch_to_blog( $origin_blog_id );
}

$avatar_full_path = get_attached_file( $local_avatars['media_id'] );
$avatar_full_path = get_attached_file( $local_avatars['media_id'] );

if ( $this->is_avatar_shared() ) {
restore_current_blog();
}
if ( $this->is_avatar_shared() ) {
restore_current_blog();
}

// has the media been deleted?
if ( ! $avatar_full_path ) {
return '';
}
// has the media been deleted?
if ( ! $avatar_full_path ) {
return '';
}

$size = (int) $size;
// Use dynamic full url in favour of host/domain change.
$local_avatars['full'] = wp_get_attachment_image_url( $local_avatars['media_id'], 'full' );

// Generate a new size.
if ( ! array_key_exists( $size, $local_avatars ) ) {
$local_avatars[ $size ] = $local_avatars['full']; // just in case of failure elsewhere

// allow automatic rescaling to be turned off
if ( apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) :
// Just in case of failure elsewhere, set the full size as default.
$local_avatars[ $size ] = $local_avatars['full'];

$upload_path = wp_upload_dir();
// allow automatic rescaling to be turned off
if ( apply_filters( 'simple_local_avatars_dynamic_resize', true ) ) :

// get path for image by converting URL, unless its already been set, thanks to using media library approach
if ( ! isset( $avatar_full_path ) ) {
$avatar_full_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $local_avatars['full'] );
}
$upload_path = wp_upload_dir();

// generate the new size
$editor = wp_get_image_editor( $avatar_full_path );
if ( ! is_wp_error( $editor ) ) {
$resized = $editor->resize( $size, $size, true );
if ( ! is_wp_error( $resized ) ) {
$dest_file = $editor->generate_filename();
$saved = $editor->save( $dest_file );
if ( ! is_wp_error( $saved ) ) {
// Transform the destination file path into URL.
$dest_file_url = '';
if ( false !== strpos( $dest_file, $upload_path['basedir'] ) ) {
$dest_file_url = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file );
} else if ( is_multisite() && false !== strpos( $dest_file, ABSPATH . 'wp-content/uploads' ) ) {
$dest_file_url = str_replace( ABSPATH . 'wp-content/uploads', network_site_url( '/wp-content/uploads' ), $dest_file );
}
// get path for image by converting URL, unless its already been set, thanks to using media library approach
if ( ! isset( $avatar_full_path ) ) {
$avatar_full_path = str_replace( $upload_path['baseurl'], $upload_path['basedir'], $local_avatars['full'] );
}

$local_avatars[ $size ] = $dest_file_url;
// generate the new size
$editor = wp_get_image_editor( $avatar_full_path );
if ( ! is_wp_error( $editor ) ) {
$resized = $editor->resize( $size, $size, true );
if ( ! is_wp_error( $resized ) ) {
$dest_file = $editor->generate_filename();
$saved = $editor->save( $dest_file );
if ( ! is_wp_error( $saved ) ) {
// Transform the destination file path into URL.
$dest_file_url = '';
if ( false !== strpos( $dest_file, $upload_path['basedir'] ) ) {
$dest_file_url = str_replace( $upload_path['basedir'], $upload_path['baseurl'], $dest_file );
} elseif ( is_multisite() && false !== strpos( $dest_file, ABSPATH . 'wp-content/uploads' ) ) {
$dest_file_url = str_replace( ABSPATH . 'wp-content/uploads', network_site_url( '/wp-content/uploads' ), $dest_file );
}

$local_avatars[ $size ] = $dest_file_url;
}
}
}

// save updated avatar sizes
update_user_meta( $user_id, $this->user_key, $local_avatars );

endif;
}
// save updated avatar sizes
update_user_meta( $user_id, $this->user_key, $local_avatars );
endif;

if ( 'http' !== substr( $local_avatars[ $size ], 0, 4 ) ) {
if ( strpos( $local_avatars[ $size ], 'http' ) !== 0 ) {
$local_avatars[ $size ] = home_url( $local_avatars[ $size ] );
}

Expand DownExpand Up@@ -1004,7 +1016,7 @@ public function assign_new_user_avatar( $url_or_media_id, $user_id ) {
*
* @param int $user_id Id of the user who's avatar was updated
*/
do_action( 'simple_local_avatar_updated' , $user_id );
do_action( 'simple_local_avatar_updated', $user_id );
}

/**
Expand DownExpand Up@@ -1411,9 +1423,9 @@ private function clear_user_avatar_cache( $local_avatars, $user_id, $media_id )
$file_name_data = pathinfo( get_attached_file( $media_id ) );
}

$file_dir_name = $file_name_data['dirname'];
$file_name = $file_name_data['filename'];
$file_ext = $file_name_data['extension'];
$file_dir_name = $file_name_data['dirname'];
$file_name = $file_name_data['filename'];
$file_ext = $file_name_data['extension'];
foreach ( $local_avatars as $local_avatars_key => $local_avatar_value ) {
if ( ! in_array( $local_avatars_key, [ 'media_id', 'full' ], true ) ) {
$file_size_path = sprintf( '%1$s/%2$s-%3$sx%3$s.%4$s', $file_dir_name, $file_name, $local_avatars_key, $file_ext );
Expand Down
16 changes: 16 additions & 0 deletions tests/phpunit/SimpleLocalAvatarsTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -64,6 +64,13 @@ public function setUp(): void {
->with( 101 )
->andReturn( '/avatar.png' );

WP_Mock::userFunction( 'wp_get_attachment_image_url' )
->with( 101, 'full' )
->andReturn( '/avatar.png' );

WP_Mock::userFunction( 'content_url' )
->andReturn( 'https://example.com/' );

WP_Mock::userFunction( 'admin_url' )
->with( 'options-discussion.php' )
->andReturn( 'wp-admin/options-discussion.php' );
Expand DownExpand Up@@ -196,9 +203,18 @@ public function test_get_simple_local_avatar_url_media_file_deleted() {
WP_Mock::userFunction( 'get_user_meta' )
->with( 2, 'simple_local_avatar', true )
->andReturn( [ 'media_id' => 102 ] );

WP_Mock::userFunction( 'get_attached_file' )
->with( 102 )
->andReturn( false );

WP_Mock::userFunction( 'wp_get_attachment_image_url' )
->with( 102, 'full' )
->andReturn( false );

WP_Mock::userFunction( 'content_url' )
->andReturn( 'http://example.com' );

$this->assertEquals( '', $this->instance->get_simple_local_avatar_url( 2, 96 ) );
}

Expand Down
34 changes: 34 additions & 0 deletions tests/phpunit/multisite/SimpleLocalAvatarsNetworkTest.php
Original file line numberDiff line numberDiff line change
Expand Up@@ -131,6 +131,40 @@ public function test_get_simple_local_avatar_url() {
'return' => '/avatar.png',
'times' => 1,
] );
WP_Mock::userFunction( 'wp_get_attachment_image_url', [
'args' => [ 101, 'full' ],
'return' => '/avatar.png',
'times' => 1,
] );
WP_Mock::userFunction( 'content_url', [
'args' => [],
'return' => 'http://example.com',
'times' => 1,
] );
WP_Mock::userFunction( 'wp_upload_dir', [
'args' => [],
'return' => ['baseurl' => '', 'basedir' => ''],
'times' => 1,
] );
WP_Mock::userFunction( 'wp_get_image_editor', [
'args' => [ '/avatar.png' ],
'return' => false,
'times' => 1,
] );
WP_Mock::userFunction( 'is_wp_error', [
'return' => true,
'times' => 1,
] );
WP_Mock::userFunction( 'update_user_meta', [
'args' => [ 1, 'simple_local_avatar', ['media_id' => 101, 'full' => '/avatar.png', 96 => '/avatar.png'] ],
'return' => true,
'times' => 1,
] );
WP_Mock::userFunction( 'home_url', [
'args' => [ '/avatar.png' ],
'return' => 'https://example.com/avatar-96x96.png',
'times' => 1,
] );
WP_Mock::userFunction( 'get_option' )
->with( 'avatar_rating' )
->andReturn( false );
Expand Down