copy_dir

The timeline below displays how wordpress function copy_dir has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.3

/**
 * Copies a directory from one location to another via the WordPress Filesystem
 * Abstraction.
 *
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 *
 * @param string   $from      Source directory.
 * @param string   $to        Destination directory.
 * @param string[] $skip_list An array of files/folders to skip copying.
 * @return true|WP_Error True on success, WP_Error on failure.
 */
function copy_dir($from, $to, $skip_list = array())
{
    global $wp_filesystem;
    $dirlist = $wp_filesystem->dirlist($from);
    if (false === $dirlist) {
        return new WP_Error('dirlist_failed_copy_dir', __('Directory listing failed.'), basename($from));
    }
    $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;
        }
        if ('f' === $fileinfo['type']) {
            if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                // If copy failed, chmod file to 0644 and try again.
                $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
                if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                    return new WP_Error('copy_failed_copy_dir', __('Could not copy file.'), $to . $filename);
                }
            }
            wp_opcache_invalidate($to . $filename);
        } elseif ('d' === $fileinfo['type']) {
            if (!$wp_filesystem->is_dir($to . $filename)) {
                if (!$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR)) {
                    return new WP_Error('mkdir_failed_copy_dir', __('Could not create directory.'), $to . $filename);
                }
            }
            // Generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list.
            $sub_skip_list = array();
            foreach ($skip_list as $skip_item) {
                if (str_starts_with($skip_item, $filename . '/')) {
                    $sub_skip_list[] = preg_replace('!^' . preg_quote($filename, '!') . '/!i', '', $skip_item);
                }
            }
            $result = copy_dir($from . $filename, $to . $filename, $sub_skip_list);
            if (is_wp_error($result)) {
                return $result;
            }
        }
    }
    return true;
}

WordPress Version: 5.7

/**
 * Copies a directory from one location to another via the WordPress Filesystem
 * Abstraction.
 *
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 *
 * @param string   $from      Source directory.
 * @param string   $to        Destination directory.
 * @param string[] $skip_list An array of files/folders to skip copying.
 * @return true|WP_Error True on success, WP_Error on failure.
 */
function copy_dir($from, $to, $skip_list = array())
{
    global $wp_filesystem;
    $dirlist = $wp_filesystem->dirlist($from);
    if (false === $dirlist) {
        return new WP_Error('dirlist_failed_copy_dir', __('Directory listing failed.'), basename($to));
    }
    $from = trailingslashit($from);
    $to = trailingslashit($to);
    foreach ((array) $dirlist as $filename => $fileinfo) {
        if (in_array($filename, $skip_list, true)) {
            continue;
        }
        if ('f' === $fileinfo['type']) {
            if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                // If copy failed, chmod file to 0644 and try again.
                $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
                if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                    return new WP_Error('copy_failed_copy_dir', __('Could not copy file.'), $to . $filename);
                }
            }
            wp_opcache_invalidate($to . $filename);
        } elseif ('d' === $fileinfo['type']) {
            if (!$wp_filesystem->is_dir($to . $filename)) {
                if (!$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR)) {
                    return new WP_Error('mkdir_failed_copy_dir', __('Could not create directory.'), $to . $filename);
                }
            }
            // Generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list.
            $sub_skip_list = array();
            foreach ($skip_list as $skip_item) {
                if (0 === strpos($skip_item, $filename . '/')) {
                    $sub_skip_list[] = preg_replace('!^' . preg_quote($filename, '!') . '/!i', '', $skip_item);
                }
            }
            $result = copy_dir($from . $filename, $to . $filename, $sub_skip_list);
            if (is_wp_error($result)) {
                return $result;
            }
        }
    }
    return true;
}

WordPress Version: 5.5

/**
 * Copies a directory from one location to another via the WordPress Filesystem
 * Abstraction.
 *
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 *
 * @param string   $from      Source directory.
 * @param string   $to        Destination directory.
 * @param string[] $skip_list An array of files/folders to skip copying.
 * @return true|WP_Error True on success, WP_Error on failure.
 */
function copy_dir($from, $to, $skip_list = array())
{
    global $wp_filesystem;
    $dirlist = $wp_filesystem->dirlist($from);
    $from = trailingslashit($from);
    $to = trailingslashit($to);
    foreach ((array) $dirlist as $filename => $fileinfo) {
        if (in_array($filename, $skip_list, true)) {
            continue;
        }
        if ('f' === $fileinfo['type']) {
            if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                // If copy failed, chmod file to 0644 and try again.
                $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
                if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                    return new WP_Error('copy_failed_copy_dir', __('Could not copy file.'), $to . $filename);
                }
            }
            wp_opcache_invalidate($to . $filename);
        } elseif ('d' === $fileinfo['type']) {
            if (!$wp_filesystem->is_dir($to . $filename)) {
                if (!$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR)) {
                    return new WP_Error('mkdir_failed_copy_dir', __('Could not create directory.'), $to . $filename);
                }
            }
            // Generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list.
            $sub_skip_list = array();
            foreach ($skip_list as $skip_item) {
                if (0 === strpos($skip_item, $filename . '/')) {
                    $sub_skip_list[] = preg_replace('!^' . preg_quote($filename, '!') . '/!i', '', $skip_item);
                }
            }
            $result = copy_dir($from . $filename, $to . $filename, $sub_skip_list);
            if (is_wp_error($result)) {
                return $result;
            }
        }
    }
    return true;
}

WordPress Version: 5.4

/**
 * Copies a directory from one location to another via the WordPress Filesystem
 * Abstraction.
 *
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 *
 * @param string   $from      Source directory.
 * @param string   $to        Destination directory.
 * @param string[] $skip_list An array of files/folders to skip copying.
 * @return true|WP_Error True on success, WP_Error on failure.
 */
function copy_dir($from, $to, $skip_list = array())
{
    global $wp_filesystem;
    $dirlist = $wp_filesystem->dirlist($from);
    $from = trailingslashit($from);
    $to = trailingslashit($to);
    foreach ((array) $dirlist as $filename => $fileinfo) {
        if (in_array($filename, $skip_list, true)) {
            continue;
        }
        if ('f' == $fileinfo['type']) {
            if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                // If copy failed, chmod file to 0644 and try again.
                $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
                if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                    return new WP_Error('copy_failed_copy_dir', __('Could not copy file.'), $to . $filename);
                }
            }
        } elseif ('d' == $fileinfo['type']) {
            if (!$wp_filesystem->is_dir($to . $filename)) {
                if (!$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR)) {
                    return new WP_Error('mkdir_failed_copy_dir', __('Could not create directory.'), $to . $filename);
                }
            }
            // Generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list.
            $sub_skip_list = array();
            foreach ($skip_list as $skip_item) {
                if (0 === strpos($skip_item, $filename . '/')) {
                    $sub_skip_list[] = preg_replace('!^' . preg_quote($filename, '!') . '/!i', '', $skip_item);
                }
            }
            $result = copy_dir($from . $filename, $to . $filename, $sub_skip_list);
            if (is_wp_error($result)) {
                return $result;
            }
        }
    }
    return true;
}

WordPress Version: 5.3

/**
 * Copies a directory from one location to another via the WordPress Filesystem
 * Abstraction.
 *
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 *
 * @param string $from     Source directory.
 * @param string $to       Destination directory.
 * @param array $skip_list A list of files/folders to skip copying.
 * @return true|WP_Error True on success, WP_Error on failure.
 */
function copy_dir($from, $to, $skip_list = array())
{
    global $wp_filesystem;
    $dirlist = $wp_filesystem->dirlist($from);
    $from = trailingslashit($from);
    $to = trailingslashit($to);
    foreach ((array) $dirlist as $filename => $fileinfo) {
        if (in_array($filename, $skip_list, true)) {
            continue;
        }
        if ('f' == $fileinfo['type']) {
            if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                // If copy failed, chmod file to 0644 and try again.
                $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
                if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                    return new WP_Error('copy_failed_copy_dir', __('Could not copy file.'), $to . $filename);
                }
            }
        } elseif ('d' == $fileinfo['type']) {
            if (!$wp_filesystem->is_dir($to . $filename)) {
                if (!$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR)) {
                    return new WP_Error('mkdir_failed_copy_dir', __('Could not create directory.'), $to . $filename);
                }
            }
            // generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list
            $sub_skip_list = array();
            foreach ($skip_list as $skip_item) {
                if (0 === strpos($skip_item, $filename . '/')) {
                    $sub_skip_list[] = preg_replace('!^' . preg_quote($filename, '!') . '/!i', '', $skip_item);
                }
            }
            $result = copy_dir($from . $filename, $to . $filename, $sub_skip_list);
            if (is_wp_error($result)) {
                return $result;
            }
        }
    }
    return true;
}

WordPress Version: 5.1

/**
 * Copies a directory from one location to another via the WordPress Filesystem
 * Abstraction.
 *
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass.
 *
 * @param string $from     Source directory.
 * @param string $to       Destination directory.
 * @param array $skip_list A list of files/folders to skip copying.
 * @return true|WP_Error True on success, WP_Error on failure.
 */
function copy_dir($from, $to, $skip_list = array())
{
    global $wp_filesystem;
    $dirlist = $wp_filesystem->dirlist($from);
    $from = trailingslashit($from);
    $to = trailingslashit($to);
    foreach ((array) $dirlist as $filename => $fileinfo) {
        if (in_array($filename, $skip_list)) {
            continue;
        }
        if ('f' == $fileinfo['type']) {
            if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                // If copy failed, chmod file to 0644 and try again.
                $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
                if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                    return new WP_Error('copy_failed_copy_dir', __('Could not copy file.'), $to . $filename);
                }
            }
        } elseif ('d' == $fileinfo['type']) {
            if (!$wp_filesystem->is_dir($to . $filename)) {
                if (!$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR)) {
                    return new WP_Error('mkdir_failed_copy_dir', __('Could not create directory.'), $to . $filename);
                }
            }
            // generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list
            $sub_skip_list = array();
            foreach ($skip_list as $skip_item) {
                if (0 === strpos($skip_item, $filename . '/')) {
                    $sub_skip_list[] = preg_replace('!^' . preg_quote($filename, '!') . '/!i', '', $skip_item);
                }
            }
            $result = copy_dir($from . $filename, $to . $filename, $sub_skip_list);
            if (is_wp_error($result)) {
                return $result;
            }
        }
    }
    return true;
}

WordPress Version: 4.3

/**
 * Copies a directory from one location to another via the WordPress Filesystem Abstraction.
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @global WP_Filesystem_Base $wp_filesystem Subclass
 *
 * @param string $from source directory
 * @param string $to destination directory
 * @param array $skip_list a list of files/folders to skip copying
 * @return mixed WP_Error on failure, True on success.
 */
function copy_dir($from, $to, $skip_list = array())
{
    global $wp_filesystem;
    $dirlist = $wp_filesystem->dirlist($from);
    $from = trailingslashit($from);
    $to = trailingslashit($to);
    foreach ((array) $dirlist as $filename => $fileinfo) {
        if (in_array($filename, $skip_list)) {
            continue;
        }
        if ('f' == $fileinfo['type']) {
            if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                // If copy failed, chmod file to 0644 and try again.
                $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
                if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                    return new WP_Error('copy_failed_copy_dir', __('Could not copy file.'), $to . $filename);
                }
            }
        } elseif ('d' == $fileinfo['type']) {
            if (!$wp_filesystem->is_dir($to . $filename)) {
                if (!$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR)) {
                    return new WP_Error('mkdir_failed_copy_dir', __('Could not create directory.'), $to . $filename);
                }
            }
            // generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list
            $sub_skip_list = array();
            foreach ($skip_list as $skip_item) {
                if (0 === strpos($skip_item, $filename . '/')) {
                    $sub_skip_list[] = preg_replace('!^' . preg_quote($filename, '!') . '/!i', '', $skip_item);
                }
            }
            $result = copy_dir($from . $filename, $to . $filename, $sub_skip_list);
            if (is_wp_error($result)) {
                return $result;
            }
        }
    }
    return true;
}

WordPress Version: 3.7

/**
 * Copies a directory from one location to another via the WordPress Filesystem Abstraction.
 * Assumes that WP_Filesystem() has already been called and setup.
 *
 * @since 2.5.0
 *
 * @param string $from source directory
 * @param string $to destination directory
 * @param array $skip_list a list of files/folders to skip copying
 * @return mixed WP_Error on failure, True on success.
 */
function copy_dir($from, $to, $skip_list = array())
{
    global $wp_filesystem;
    $dirlist = $wp_filesystem->dirlist($from);
    $from = trailingslashit($from);
    $to = trailingslashit($to);
    foreach ((array) $dirlist as $filename => $fileinfo) {
        if (in_array($filename, $skip_list)) {
            continue;
        }
        if ('f' == $fileinfo['type']) {
            if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                // If copy failed, chmod file to 0644 and try again.
                $wp_filesystem->chmod($to . $filename, FS_CHMOD_FILE);
                if (!$wp_filesystem->copy($from . $filename, $to . $filename, true, FS_CHMOD_FILE)) {
                    return new WP_Error('copy_failed_copy_dir', __('Could not copy file.'), $to . $filename);
                }
            }
        } elseif ('d' == $fileinfo['type']) {
            if (!$wp_filesystem->is_dir($to . $filename)) {
                if (!$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR)) {
                    return new WP_Error('mkdir_failed_copy_dir', __('Could not create directory.'), $to . $filename);
                }
            }
            // generate the $sub_skip_list for the subdirectory as a sub-set of the existing $skip_list
            $sub_skip_list = array();
            foreach ($skip_list as $skip_item) {
                if (0 === strpos($skip_item, $filename . '/')) {
                    $sub_skip_list[] = preg_replace('!^' . preg_quote($filename, '!') . '/!i', '', $skip_item);
                }
            }
            $result = copy_dir($from . $filename, $to . $filename, $sub_skip_list);
            if (is_wp_error($result)) {
                return $result;
            }
        }
    }
    return true;
}