How to remove a directory in wordpress using Filesystem_API

Viewed 2996

I am using WordPress 4.8.1

I am trying to remove a directory from theme setting, but neither getting any error nor any success. Even PHP error log has not logged data about it, My WP_DEBUG is on.

$wp_filesystem_base = WP_Filesystem_Base();
$wp_filesystem_base->rmdir(dirname($file_path), true);

The class is not undefined for sure as I could have got some error, still I used a class_exists to check it and it is available where I am using.

please let me know, if I am doing it wrong or need any thing more about the issue.

5 Answers

Since a WordPress' core methods working answer is missing here, I propose this complete solution that sums up all the other aswers.

require_once ( ABSPATH . 'wp-admin/includes/class-wp-filesystem-base.php' );
require_once ( ABSPATH . 'wp-admin/includes/class-wp-filesystem-direct.php' );
$fileSystemDirect = new WP_Filesystem_Direct(false);
$fileSystemDirect->rmdir($dir, true);

Summary:

  • You can't use WP_Filesystem_Base because does not really implement the method rmdir; it's just an interface.
  • You must require class-wp-filesystem-base.php because it's a dependency of WP_Filesystem_Direct
  • You can always use your own rrmdir as someone proposed, but you don't have to add additional code to be maintained when a feature is already available in core;
  • The false argument passed to the constructor is just because the $arg param is needed but not used as explained in official WP's documentation.

I guess you need to use WP_Filesystem_Direct class

WP_Filesystem_Base::rmdir implementation:

public function rmdir( $path, $recursive = false ) {
    return false;
}

You can see, that this code is not working with real FS :)

So, WP_Filesystem_Direct::rmdir actually do the job.

I got it to work like this:

/**
 * Deletes a directory, using the WordPress Filesystem API
 *
 * @param string $path
 * @return void
 * @author Rasso Hilber <mail@rassohilber.com>
 */
function delete_directory(string $path) {
  // make it work from the frontend, as well
  require_once ABSPATH . 'wp-admin/includes/file.php';
  // this variable will hold the selected filesystem class
  global $wp_filesystem;
  // this function selects the appropriate filesystem class
  WP_Filesystem();
  // finally, you can call the 'delete' function on the selected class,
  // which is now stored in the global '$wp_filesystem'
  $wp_filesystem->delete($path, true);
}

Finally I ended with using a core php function, I believe it is a workaround, but will be useful for someone for who the above code or

$wp_filesystem_direct = WP_Filesystem_Direct();
$wp_filesystem_direct->rmdir(dirname($file_path), true);

will not work. You can use this

function rrmdir($dir) {
       if (is_dir($dir)) { 
         $objects = scandir($dir); 
         foreach ($objects as $object) { 
           if ($object != "." && $object != "..") { 
             if (filetype($dir."/".$object) == "dir") self::rrmdir($dir."/".$object); else unlink($dir."/".$object); 
           } 
         } 
         reset($objects); 
         rmdir($dir); 
       } 
    }

This works for me:

require_once ( ABSPATH . '\wp-admin\includes\class-wp-filesystem-direct.php' );
$fileSystemDirect = new WP_Filesystem_Direct(false);
$fileSystemDirect->rmdir($dir, true);

Or simply:

WP_Filesystem();
global $wp_filesystem;
$wp_filesystem->rmdir($dir, true);
Related