/**
  * {@inheritdoc}
  */
 public function execute(array $args, array $state = array())
 {
     if (!isset($args['dir'])) {
         return new WP_Error('no_dir', __('Dir not specified', 'fw'));
     }
     $dir = $args['dir'];
     if (file_exists($dir)) {
         if (!fw_ext_backups_rmdir_recursive($dir)) {
             return new WP_Error('rmdir_fail', __('Cannot remove directory', 'fw') . ': ' . $dir);
         }
     }
     if (!mkdir($dir, 0777, true)) {
         return new WP_Error('mkdir_fail', __('Cannot create directory', 'fw') . ': ' . $dir);
     }
     $backups_dir = fw_ext('backups')->get_backups_dir();
     if (!file_exists("{$backups_dir}/index.php")) {
         $contents = implode("\n", array('<?php', 'header(\'HTTP/1.0 403 Forbidden\');', 'die(\'<h1>Forbidden</h1>\');'));
         if (@file_put_contents("{$backups_dir}/index.php", $contents) === false) {
             return new WP_Error('index_create_fail', sprintf(__('Cannot create file: %s', 'fw'), "{$backups_dir}/index.php"));
         }
     }
     if (!file_exists("{$backups_dir}/.htaccess")) {
         $contents = implode("\n", array('Deny from all', '<IfModule mod_rewrite.c>', '    RewriteEngine On', '    RewriteRule . - [R=404,L]', '</IfModule>'));
         if (@file_put_contents("{$backups_dir}/.htaccess", $contents) === false) {
             return new WP_Error('htaccess_create_fail', sprintf(__('Cannot create file: %s', 'fw'), "{$backups_dir}/htaccess"));
         }
     }
     return true;
 }
function fw_ext_backups_rmdir_recursive($dir)
{
    if (is_dir($dir)) {
        if ($paths = glob($dir . '/{,.}[!.,!..]*', GLOB_MARK | GLOB_BRACE)) {
            foreach ($paths as $file) {
                $file = fw_fix_path($file);
                if (is_dir($file)) {
                    if (!fw_ext_backups_rmdir_recursive($file)) {
                        return false;
                    }
                } else {
                    if (!unlink($file)) {
                        return false;
                    }
                }
            }
        }
        if (!rmdir($dir)) {
            return false;
        }
        return true;
    }
    return false;
}
function fw_ext_backups_rmdir_recursive($dir)
{
    if (is_dir($dir = fw_fix_path($dir))) {
        if ($files = array_diff(($files = scandir($dir)) ? $files : array(), array('.', '..'))) {
            foreach ($files as $file) {
                $file = $dir . '/' . $file;
                if (is_dir($file)) {
                    if (!fw_ext_backups_rmdir_recursive($file)) {
                        return false;
                    }
                } else {
                    if (!unlink($file)) {
                        return false;
                    }
                }
            }
        }
        if (!rmdir($dir)) {
            return false;
        }
        return true;
    }
    return false;
}
 /**
  * @param string $dir path
  * @param bool $fs Use WP_Filesystem or not
  * @param array $skip_dirs {'path': mixed}
  *
  * @return WP_Error|true
  */
 private function clear_dir($dir, $fs, $skip_dirs)
 {
     $included_hidden_names = fw_ext('backups')->get_config('included_hidden_names');
     if ($fs) {
         global $wp_filesystem;
         /** @var WP_Filesystem_Base $wp_filesystem */
         $fs_dir = fw_fix_path(FW_WP_Filesystem::real_path_to_filesystem_path($dir));
         if (empty($fs_dir)) {
             return new WP_Error('dir_to_fs_failed', sprintf(__('Cannot convert Filesystem path: %s', 'fw'), $dir));
         } elseif (false === ($list = $wp_filesystem->dirlist($fs_dir, true))) {
             return new WP_Error('dir_list_failed', sprintf(__('Failed to list dir: %s', 'fw'), $dir));
         }
         foreach ($list as $file) {
             if ($file['name'][0] === '.' && !isset($included_hidden_names[$file['name']])) {
                 continue;
             }
             $file_path = $dir . '/' . $file['name'];
             $fs_file_path = $fs_dir . '/' . $file['name'];
             if ($file['type'] === 'd') {
                 if (isset($skip_dirs[$file_path])) {
                     continue;
                 } else {
                     foreach ($skip_dirs as $skip_dir => $skip_dir_data) {
                         if (strlen(preg_replace('/^' . preg_quote($file_path, '/') . '/', '', $skip_dir)) != strlen($skip_dir)) {
                             continue 2;
                             // skip dir if it's inside current dir
                         }
                     }
                 }
                 if (!$wp_filesystem->rmdir($fs_file_path, true)) {
                     return new WP_Error('dir_rm_fail', sprintf(__('Failed to remove dir: %s', 'fw'), $file_path));
                 }
             } else {
                 if (!$wp_filesystem->delete($fs_file_path)) {
                     return new WP_Error('file_rm_fail', sprintf(__('Failed to remove file: %s', 'fw'), $file_path));
                 }
             }
         }
         return true;
     } else {
         $files = array_diff(($files = scandir($dir)) ? $files : array(), array('.', '..'));
         foreach ($files as $file_name) {
             $file_path = $dir . '/' . $file_name;
             if ($file_name[0] === '.' && !isset($included_hidden_names[$file_name])) {
                 continue;
             }
             if (is_dir($file_path)) {
                 if (isset($skip_dirs[$file_path])) {
                     continue;
                 } else {
                     foreach ($skip_dirs as $skip_dir => $skip_dir_data) {
                         if (strlen(preg_replace('/^' . preg_quote($file_path, '/') . '/', '', $skip_dir)) != strlen($skip_dir)) {
                             continue 2;
                             // skip dir it's inside current dir
                         }
                     }
                 }
                 if (!fw_ext_backups_rmdir_recursive($file_path)) {
                     return new WP_Error('dir_rm_fail', sprintf(__('Failed to remove dir: %s', 'fw'), $file_path));
                 }
             } else {
                 if (!unlink($file_path)) {
                     return new WP_Error('file_rm_fail', sprintf(__('Failed to remove file: %s', 'fw'), $file_path));
                 }
             }
         }
         return true;
     }
 }