diff --git a/inc/media_offload.php b/inc/media_offload.php index cd66df44..b12ca246 100644 --- a/inc/media_offload.php +++ b/inc/media_offload.php @@ -161,8 +161,14 @@ public static function instance() { self::$instance->init(); } if ( self::$instance->settings->is_offload_enabled() ) { + // While a rollback runs, offloaded images are still served from Optimole, but new uploads + // stay local: offloading them and their filename deduplication needs offload_media on. + $offload_new_uploads = self::$instance->settings->get( 'offload_media' ) === 'enabled'; + add_filter( 'image_downsize', [ self::$instance, 'generate_filter_downsize_urls' ], 10, 3 ); - add_filter( 'wp_generate_attachment_metadata', [ self::$instance, 'generate_image_meta' ], 10, 2 ); + if ( $offload_new_uploads ) { + add_filter( 'wp_generate_attachment_metadata', [ self::$instance, 'generate_image_meta' ], 10, 2 ); + } add_filter( 'wp_get_attachment_url', [ self::$instance, 'get_image_attachment_url' ], - 999, 2 ); add_filter( 'wp_insert_post_data', [ self::$instance, 'filter_uploaded_images' ] ); @@ -176,12 +182,15 @@ public static function instance() { add_filter( 'wp_calculate_image_srcset', [ self::$instance, 'calculate_image_srcset' ], 1, 5 ); add_action( 'post_updated', [ self::$instance, 'update_offload_meta' ], 10, 3 ); - // Backwards compatibility for older versions of WordPress < 6.0.0 requiring 3 parameters for this specific filter. - $below_6_0_0 = version_compare( get_bloginfo( 'version' ), '6.0.0', '<' ); - if ( $below_6_0_0 ) { - add_filter( 'wp_insert_attachment_data', [ self::$instance, 'insert_legacy' ], 10, 3 ); - } else { - add_filter( 'wp_insert_attachment_data', [ self::$instance, 'insert' ], 10, 4 ); + // Local uploads keep WordPress's own filename deduplication. + if ( $offload_new_uploads ) { + // Backwards compatibility for older versions of WordPress < 6.0.0 requiring 3 parameters for this specific filter. + $below_6_0_0 = version_compare( get_bloginfo( 'version' ), '6.0.0', '<' ); + if ( $below_6_0_0 ) { + add_filter( 'wp_insert_attachment_data', [ self::$instance, 'insert_legacy' ], 10, 3 ); + } else { + add_filter( 'wp_insert_attachment_data', [ self::$instance, 'insert' ], 10, 4 ); + } } add_action( 'optml_start_processing_images', [ self::$instance, 'start_processing_images' ], 10, 6 ); diff --git a/tests/test-media.php b/tests/test-media.php index 529b5373..37e5d63b 100644 --- a/tests/test-media.php +++ b/tests/test-media.php @@ -224,6 +224,31 @@ static function unlinkRecursive( $pattern, $files ) { } } } + /** + * While a rollback runs (offload_media off, rollback_status on), offloaded images are still + * served from Optimole, but a new upload stays in the media library. + */ + public function test_upload_during_rollback_stays_local(): void { + $settings = new Optml_Settings(); + $settings->update( 'offload_media', 'disabled' ); + $settings->update( 'rollback_status', 'enabled' ); + + // The hooks of this request, registered with the rollback state. + remove_all_filters( 'wp_generate_attachment_metadata' ); + remove_all_filters( 'wp_insert_attachment_data' ); + Optml_Media_Offload::instance(); + + $this->assertFalse( has_filter( 'wp_generate_attachment_metadata' ) ); + $this->assertFalse( has_filter( 'wp_insert_attachment_data' ) ); + $this->assertNotFalse( has_filter( 'wp_get_attachment_url' ), 'Offloaded images are still served from Optimole.' ); + + $attachment_id = self::factory()->attachment->create_upload_object( OPTML_PATH . 'tests/assets/' . self::$files[0] . '.jpg' ); + $meta = wp_get_attachment_metadata( $attachment_id ); + + $this->assertFalse( Optml_Media_Offload::is_uploaded_image( $meta['file'] ) ); + $this->assertFileExists( get_attached_file( $attachment_id ) ); + } + public function test_retryable_error() { Optml_Media_Offload::instance()->rollback_and_update_images([self::$sample_attachement]); self::$error_mark = true;