From 8c892d105f5383fd9b0c5869faf6d79871c678f2 Mon Sep 17 00:00:00 2001 From: Jeremy Felt Date: Fri, 12 Jan 2018 13:31:31 -0800 Subject: [PATCH 1/2] Don't filter absolute paths when deleting an original file The `wp_delete_file` filter is used in two different ways. When filtering the filename for the removal of thumbnails, extra image sizes, and backup sizes, a relative path is expected in return. This relative path is then used to rebuild the absolute path before `unlink()` fires. When filtering directly in `wp_delete_file()`, an absolute path is expected at all times. This fixes a case where original files would not be deleted from S3 when removed from the media library, but where all of the thumbnails would be deleted. See https://github.com/humanmade/S3-Uploads/issues/92 See https://core.trac.wordpress.org/ticket/39476 --- inc/class-s3-uploads.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/inc/class-s3-uploads.php b/inc/class-s3-uploads.php index 9ea247b8..43305d89 100644 --- a/inc/class-s3-uploads.php +++ b/inc/class-s3-uploads.php @@ -9,6 +9,7 @@ class S3_Uploads { private $secret; public $original_upload_dir; + public $original_file; /** * @@ -46,6 +47,7 @@ public function setup() { add_filter( 'upload_dir', array( $this, 'filter_upload_dir' ) ); add_filter( 'wp_image_editors', array( $this, 'filter_editors' ), 9 ); + add_action( 'delete_attachment', array( $this, 'set_original_file' ) ); add_filter( 'wp_delete_file', array( $this, 'wp_filter_delete_file' ) ); add_filter( 'wp_read_image_metadata', array( $this, 'wp_filter_read_image_metadata' ), 10, 2 ); remove_filter( 'admin_notices', 'wpthumb_errors' ); @@ -102,6 +104,17 @@ public function filter_upload_dir( $dirs ) { return $dirs; } + /** + * Capture the full path to the original file being deleted. This + * is used when determining whether an absolute or relative path + * should be used when deleting the file. + * + * @param $post_id + */ + public function set_original_file( $post_id ) { + $this->original_file = get_attached_file( $post_id ); + } + /** * When WordPress removes files, it's expecting to do so on * absolute file paths, as such it breaks when using uris for @@ -115,6 +128,11 @@ public function filter_upload_dir( $dirs ) { public function wp_filter_delete_file( $file_path ) { $dir = wp_upload_dir(); + // When `wp_delete_file()` is called directly, it expects an absolute path. + if ( $file_path === $this->original_file ) { + return $file_path; + } + return str_replace( trailingslashit( $dir['basedir'] ), '', $file_path ); } From 1e353ed1b85723baedb750abf62f5fc9236214d5 Mon Sep 17 00:00:00 2001 From: Jeremy Felt Date: Fri, 12 Jan 2018 13:54:29 -0800 Subject: [PATCH 2/2] Leave file path untouched if not deleting an attachment When `wp_delete_file()` is used directly, then we can assume that the `delete_attachment` hook does not fire and the absolute file path can be returned untouched. --- inc/class-s3-uploads.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/class-s3-uploads.php b/inc/class-s3-uploads.php index 43305d89..bc2d47d1 100644 --- a/inc/class-s3-uploads.php +++ b/inc/class-s3-uploads.php @@ -129,7 +129,7 @@ public function wp_filter_delete_file( $file_path ) { $dir = wp_upload_dir(); // When `wp_delete_file()` is called directly, it expects an absolute path. - if ( $file_path === $this->original_file ) { + if ( ! $this->original_file || $file_path === $this->original_file ) { return $file_path; }