diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index ca75342488462..caa71d325b6e2 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -1910,6 +1910,14 @@ function copy_dir( $from, $to, $skip_list = array() ) { $from = trailingslashit( $from ); $to = trailingslashit( $to ); + if ( ! $wp_filesystem->exists( $to ) && ! $wp_filesystem->mkdir( $to ) ) { + return new WP_Error( + 'mkdir_destination_failed_copy_dir', + __( 'Could not create the destination directory.' ), + basename( $to ) + ); + } + foreach ( (array) $dirlist as $filename => $fileinfo ) { if ( in_array( $filename, $skip_list, true ) ) { continue; diff --git a/tests/phpunit/tests/filesystem/copyDir.php b/tests/phpunit/tests/filesystem/copyDir.php new file mode 100644 index 0000000000000..7b03ab88e98d5 --- /dev/null +++ b/tests/phpunit/tests/filesystem/copyDir.php @@ -0,0 +1,83 @@ +mkdir( self::$test_dir ); + } + + /** + * Removes the test directory after each test. + */ + public function tear_down() { + global $wp_filesystem; + + // Delete the root directory and its contents. + $wp_filesystem->delete( self::$test_dir, true ); + + parent::tear_down(); + } + + /** + * Tests that the destination is created if it does not already exist. + * + * @ticket 41855 + */ + public function test_should_create_destination_it_if_does_not_exist() { + global $wp_filesystem; + + $from = self::$test_dir . 'folder1/folder2/'; + $to = self::$test_dir . 'folder3/folder2/'; + + // Create the file structure for the test. + $wp_filesystem->mkdir( self::$test_dir . 'folder1' ); + $wp_filesystem->mkdir( self::$test_dir . 'folder3' ); + $wp_filesystem->mkdir( $from ); + $wp_filesystem->touch( $from . 'file1.txt' ); + $wp_filesystem->mkdir( $from . 'subfolder1' ); + $wp_filesystem->touch( $from . 'subfolder1/file2.txt' ); + + $this->assertTrue( copy_dir( $from, $to ), 'copy_dir() failed.' ); + + $this->assertDirectoryExists( $to, 'The destination was not created.' ); + $this->assertFileExists( $to . 'file1.txt', 'The destination file was not created.' ); + + $this->assertDirectoryExists( $to . 'subfolder1/', 'The destination subfolder was not created.' ); + $this->assertFileExists( $to . 'subfolder1/file2.txt', 'The destination subfolder file was not created.' ); + } + +}