Prevent wpmu_delete_blog from removing the wrong uploads directory

`wp_upload_dir()` includes some logic to fall back to the default site's upload directory if a specific directory for the requested site cannot be found. Because of this, if `wpmu_delete_blog()` is fired twice in a row for the same site, the main site's upload directory could be deleted as well.

This adds some checks in `wpmu_delete_blog()` so that we are confident in the site and it's upload directory's existence before dropping the site. Tests are added for when `ms_files_rewriting` is enabled or disabled.

Fixes #30121


git-svn-id: https://develop.svn.wordpress.org/trunk@30404 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jeremy Felt 2014-11-20 06:52:07 +00:00
parent 642f9cc7e7
commit 3223d4a4b3
3 changed files with 79 additions and 3 deletions

View File

@ -85,11 +85,26 @@ function wpmu_delete_blog( $blog_id, $drop = false ) {
$current_site = get_current_site();
// Don't destroy the initial, main, or root blog.
if ( $drop && ( 1 == $blog_id || is_main_site( $blog_id ) || ( $blog->path == $current_site->path && $blog->domain == $current_site->domain ) ) )
// If a full blog object is not available, do not destroy anything.
if ( $drop && ! $blog ) {
$drop = false;
}
// Don't destroy the initial, main, or root blog.
if ( $drop && ( 1 == $blog_id || is_main_site( $blog_id ) || ( $blog->path == $current_site->path && $blog->domain == $current_site->domain ) ) ) {
$drop = false;
}
$upload_path = trim( get_option( 'upload_path' ) );
// If ms_files_rewriting is enabled and upload_path is empty, wp_upload_dir is not reliable.
if ( $drop && get_site_option( 'ms_files_rewriting' ) && empty( $upload_path ) ) {
$drop = false;
}
if ( $drop ) {
$uploads = wp_upload_dir();
$tables = $wpdb->tables( 'blog' );
/**
* Filter the tables to drop when the blog is deleted.
@ -107,7 +122,6 @@ function wpmu_delete_blog( $blog_id, $drop = false ) {
$wpdb->delete( $wpdb->blogs, array( 'blog_id' => $blog_id ) );
$uploads = wp_upload_dir();
/**
* Filter the upload base directory to delete when the blog is deleted.
*

View File

@ -55,6 +55,37 @@ class Tests_Multisite_MS_Files_Rewriting extends WP_UnitTestCase {
$this->assertEquals( '', $info2['error'] );
restore_current_blog();
}
/**
* When a site is deleted with wpmu_delete_blog(), only the files associated with
* that site should be removed. When wpmu_delete_blog() is run a second time, nothing
* should change with upload directories.
*/
function test_upload_directories_after_multiple_wpmu_delete_blog_with_ms_files() {
$filename = rand_str().'.jpg';
$contents = rand_str();
// Upload a file to the main site on the network.
$file1 = wp_upload_bits( $filename, null, $contents );
$blog_id = $this->factory->blog->create();
switch_to_blog( $blog_id );
$file2 = wp_upload_bits( $filename, null, $contents );
restore_current_blog();
wpmu_delete_blog( $blog_id, true );
// The file on the main site should still exist. The file on the deleted site should not.
$this->assertTrue( file_exists( $file1['file'] ) );
$this->assertFalse( file_exists( $file2['file'] ) );
wpmu_delete_blog( $blog_id, true );
// The file on the main site should still exist. The file on the deleted site should not.
$this->assertTrue( file_exists( $file1['file'] ) );
$this->assertFalse( file_exists( $file2['file'] ) );
}
}
endif;

View File

@ -274,6 +274,37 @@ class Tests_Multisite_Site extends WP_UnitTestCase {
$this->assertEquals( 1, get_blog_count() );
}
/**
* When a site is deleted with wpmu_delete_blog(), only the files associated with
* that site should be removed. When wpmu_delete_blog() is run a second time, nothing
* should change with upload directories.
*/
function test_upload_directories_after_multiple_wpmu_delete_blog() {
$filename = rand_str().'.jpg';
$contents = rand_str();
// Upload a file to the main site on the network.
$file1 = wp_upload_bits( $filename, null, $contents );
$blog_id = $this->factory->blog->create();
switch_to_blog( $blog_id );
$file2 = wp_upload_bits( $filename, null, $contents );
restore_current_blog();
wpmu_delete_blog( $blog_id, true );
// The file on the main site should still exist. The file on the deleted site should not.
$this->assertTrue( file_exists( $file1['file'] ) );
$this->assertFalse( file_exists( $file2['file'] ) );
wpmu_delete_blog( $blog_id, true );
// The file on the main site should still exist. The file on the deleted site should not.
$this->assertTrue( file_exists( $file1['file'] ) );
$this->assertFalse( file_exists( $file2['file'] ) );
}
function test_wpmu_update_blogs_date() {
global $wpdb;