Exemple #1
0
/**
 * Upgrade the core of WordPress.
 *
 * This will create a .maintenance file at the base of the WordPress directory
 * to ensure that people can not access the web site, when the files are being
 * copied to their locations.
 *
 * The files in the {@link $_old_files} list will be removed and the new files
 * copied from the zip file after the database is upgraded.
 *
 * The files in the {@link $_new_bundled_files} list will be added to the installation
 * if the version is greater than or equal to the old version being upgraded.
 *
 * The steps for the upgrader for after the new release is downloaded and
 * unzipped is:
 *   1. Test unzipped location for select files to ensure that unzipped worked.
 *   2. Create the .maintenance file in current WordPress base.
 *   3. Copy new WordPress directory over old WordPress files.
 *   4. Upgrade WordPress to new version.
 *     4.1. Copy all files/folders other than wp-content
 *     4.2. Copy any language files to WP_LANG_DIR (which may differ from WP_CONTENT_DIR
 *     4.3. Copy any new bundled themes/plugins to their respective locations
 *   5. Delete new WordPress directory path.
 *   6. Delete .maintenance file.
 *   7. Remove old files.
 *   8. Delete 'update_core' option.
 *
 * There are several areas of failure. For instance if PHP times out before step
 * 6, then you will not be able to access any portion of your site. Also, since
 * the upgrade will not continue where it left off, you will not be able to
 * automatically remove old files and remove the 'update_core' option. This
 * isn't that bad.
 *
 * If the copy of the new WordPress over the old fails, then the worse is that
 * the new WordPress directory will remain.
 *
 * If it is assumed that every file will be copied over, including plugins and
 * themes, then if you edit the default theme, you should rename it, so that
 * your changes remain.
 *
 * @since 2.7.0
 *
 * @global WP_Filesystem_Base $wp_filesystem
 * @global array              $_old_files
 * @global array              $_new_bundled_files
 * @global wpdb               $wpdb
 * @global string             $wp_version
 * @global string             $required_php_version
 * @global string             $required_mysql_version
 *
 * @param string $from New release unzipped path.
 * @param string $to   Path to old WordPress installation.
 * @return WP_Error|null WP_Error on failure, null on success.
 */
function update_core($from, $to)
{
    global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;
    @set_time_limit(300);
    /**
     * Filter feedback messages displayed during the core update process.
     *
     * The filter is first evaluated after the zip file for the latest version
     * has been downloaded and unzipped. It is evaluated five more times during
     * the process:
     *
     * 1. Before WordPress begins the core upgrade process.
     * 2. Before Maintenance Mode is enabled.
     * 3. Before WordPress begins copying over the necessary files.
     * 4. Before Maintenance Mode is disabled.
     * 5. Before the database is upgraded.
     *
     * @since 2.5.0
     *
     * @param string $feedback The core update feedback messages.
     */
    apply_filters('update_feedback', __('Verifying the unpacked files…'));
    // Sanity check the unzipped distribution.
    $distro = '';
    $roots = array('/wordpress/', '/wordpress-mu/');
    foreach ($roots as $root) {
        if ($wp_filesystem->exists($from . $root . 'readme.html') && $wp_filesystem->exists($from . $root . 'wp-includes/version.php')) {
            $distro = $root;
            break;
        }
    }
    if (!$distro) {
        $wp_filesystem->delete($from, true);
        return new WP_Error('insane_distro', __('The update could not be unpacked'));
    }
    /**
     * Import $wp_version, $required_php_version, and $required_mysql_version from the new version
     * $wp_filesystem->wp_content_dir() returned unslashed pre-2.8
     *
     * @global string $wp_version
     * @global string $required_php_version
     * @global string $required_mysql_version
     */
    global $wp_version, $required_php_version, $required_mysql_version;
    $versions_file = trailingslashit($wp_filesystem->wp_content_dir()) . 'upgrade/version-current.php';
    if (!$wp_filesystem->copy($from . $distro . 'wp-includes/version.php', $versions_file)) {
        $wp_filesystem->delete($from, true);
        return new WP_Error('copy_failed_for_version_file', __('The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.'), 'wp-includes/version.php');
    }
    $wp_filesystem->chmod($versions_file, FS_CHMOD_FILE);
    require WP_CONTENT_DIR . '/upgrade/version-current.php';
    $wp_filesystem->delete($versions_file);
    $php_version = phpversion();
    $mysql_version = $wpdb->db_version();
    $old_wp_version = $wp_version;
    // The version of WordPress we're updating from
    $development_build = false !== strpos($old_wp_version . $wp_version, '-');
    // a dash in the version indicates a Development release
    $php_compat = version_compare($php_version, $required_php_version, '>=');
    if (file_exists(WP_CONTENT_DIR . '/db.php') && empty($wpdb->is_mysql)) {
        $mysql_compat = true;
    } else {
        $mysql_compat = version_compare($mysql_version, $required_mysql_version, '>=');
    }
    if (!$mysql_compat || !$php_compat) {
        $wp_filesystem->delete($from, true);
    }
    if (!$mysql_compat && !$php_compat) {
        return new WP_Error('php_mysql_not_compatible', sprintf(__('The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.'), $wp_version, $required_php_version, $required_mysql_version, $php_version, $mysql_version));
    } elseif (!$php_compat) {
        return new WP_Error('php_not_compatible', sprintf(__('The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.'), $wp_version, $required_php_version, $php_version));
    } elseif (!$mysql_compat) {
        return new WP_Error('mysql_not_compatible', sprintf(__('The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.'), $wp_version, $required_mysql_version, $mysql_version));
    }
    /** This filter is documented in wp-admin/includes/update-core.php */
    apply_filters('update_feedback', __('Preparing to install the latest version…'));
    // Don't copy wp-content, we'll deal with that below
    // We also copy version.php last so failed updates report their old version
    $skip = array('wp-content', 'wp-includes/version.php');
    $check_is_writable = array();
    // Check to see which files don't really need updating - only available for 3.7 and higher
    if (function_exists('get_core_checksums')) {
        // Find the local version of the working directory
        $working_dir_local = WP_CONTENT_DIR . '/upgrade/' . basename($from) . $distro;
        $checksums = get_core_checksums($wp_version, isset($wp_local_package) ? $wp_local_package : 'en_US');
        if (is_array($checksums) && isset($checksums[$wp_version])) {
            $checksums = $checksums[$wp_version];
        }
        // Compat code for 3.7-beta2
        if (is_array($checksums)) {
            foreach ($checksums as $file => $checksum) {
                if ('wp-content' == substr($file, 0, 10)) {
                    continue;
                }
                if (!file_exists(ABSPATH . $file)) {
                    continue;
                }
                if (!file_exists($working_dir_local . $file)) {
                    continue;
                }
                if (md5_file(ABSPATH . $file) === $checksum) {
                    $skip[] = $file;
                } else {
                    $check_is_writable[$file] = ABSPATH . $file;
                }
            }
        }
    }
    // If we're using the direct method, we can predict write failures that are due to permissions.
    if ($check_is_writable && 'direct' === $wp_filesystem->method) {
        $files_writable = array_filter($check_is_writable, array($wp_filesystem, 'is_writable'));
        if ($files_writable !== $check_is_writable) {
            $files_not_writable = array_diff_key($check_is_writable, $files_writable);
            foreach ($files_not_writable as $relative_file_not_writable => $file_not_writable) {
                // If the writable check failed, chmod file to 0644 and try again, same as copy_dir().
                $wp_filesystem->chmod($file_not_writable, FS_CHMOD_FILE);
                if ($wp_filesystem->is_writable($file_not_writable)) {
                    unset($files_not_writable[$relative_file_not_writable]);
                }
            }
            // Store package-relative paths (the key) of non-writable files in the WP_Error object.
            $error_data = version_compare($old_wp_version, '3.7-beta2', '>') ? array_keys($files_not_writable) : '';
            if ($files_not_writable) {
                return new WP_Error('files_not_writable', __('The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.'), implode(', ', $error_data));
            }
        }
    }
    /** This filter is documented in wp-admin/includes/update-core.php */
    apply_filters('update_feedback', __('Enabling Maintenance mode…'));
    // Create maintenance file to signal that we are upgrading
    $maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
    $maintenance_file = $to . '.maintenance';
    $wp_filesystem->delete($maintenance_file);
    $wp_filesystem->put_contents($maintenance_file, $maintenance_string, FS_CHMOD_FILE);
    /** This filter is documented in wp-admin/includes/update-core.php */
    apply_filters('update_feedback', __('Copying the required files&#8230;'));
    // Copy new versions of WP files into place.
    $result = _copy_dir($from . $distro, $to, $skip);
    if (is_wp_error($result)) {
        $result = new WP_Error($result->get_error_code(), $result->get_error_message(), substr($result->get_error_data(), strlen($to)));
    }
    // Since we know the core files have copied over, we can now copy the version file
    if (!is_wp_error($result)) {
        if (!$wp_filesystem->copy($from . $distro . 'wp-includes/version.php', $to . 'wp-includes/version.php', true)) {
            $wp_filesystem->delete($from, true);
            $result = new WP_Error('copy_failed_for_version_file', __('The update cannot be installed because we will be unable to copy some files. This is usually due to inconsistent file permissions.'), 'wp-includes/version.php');
        }
        $wp_filesystem->chmod($to . 'wp-includes/version.php', FS_CHMOD_FILE);
    }
    // Check to make sure everything copied correctly, ignoring the contents of wp-content
    $skip = array('wp-content');
    $failed = array();
    if (isset($checksums) && is_array($checksums)) {
        foreach ($checksums as $file => $checksum) {
            if ('wp-content' == substr($file, 0, 10)) {
                continue;
            }
            if (!file_exists($working_dir_local . $file)) {
                continue;
            }
            if (file_exists(ABSPATH . $file) && md5_file(ABSPATH . $file) == $checksum) {
                $skip[] = $file;
            } else {
                $failed[] = $file;
            }
        }
    }
    // Some files didn't copy properly
    if (!empty($failed)) {
        $total_size = 0;
        foreach ($failed as $file) {
            if (file_exists($working_dir_local . $file)) {
                $total_size += filesize($working_dir_local . $file);
            }
        }
        // If we don't have enough free space, it isn't worth trying again.
        // Unlikely to be hit due to the check in unzip_file().
        $available_space = @disk_free_space(ABSPATH);
        if ($available_space && $total_size >= $available_space) {
            $result = new WP_Error('disk_full', __('There is not enough free disk space to complete the update.'));
        } else {
            $result = _copy_dir($from . $distro, $to, $skip);
            if (is_wp_error($result)) {
                $result = new WP_Error($result->get_error_code() . '_retry', $result->get_error_message(), substr($result->get_error_data(), strlen($to)));
            }
        }
    }
    // Custom Content Directory needs updating now.
    // Copy Languages
    if (!is_wp_error($result) && $wp_filesystem->is_dir($from . $distro . 'wp-content/languages')) {
        if (WP_LANG_DIR != ABSPATH . WPINC . '/languages' || @is_dir(WP_LANG_DIR)) {
            $lang_dir = WP_LANG_DIR;
        } else {
            $lang_dir = WP_CONTENT_DIR . '/languages';
        }
        if (!@is_dir($lang_dir) && 0 === strpos($lang_dir, ABSPATH)) {
            // Check the language directory exists first
            $wp_filesystem->mkdir($to . str_replace(ABSPATH, '', $lang_dir), FS_CHMOD_DIR);
            // If it's within the ABSPATH we can handle it here, otherwise they're out of luck.
            clearstatcache();
            // for FTP, Need to clear the stat cache
        }
        if (@is_dir($lang_dir)) {
            $wp_lang_dir = $wp_filesystem->find_folder($lang_dir);
            if ($wp_lang_dir) {
                $result = copy_dir($from . $distro . 'wp-content/languages/', $wp_lang_dir);
                if (is_wp_error($result)) {
                    $result = new WP_Error($result->get_error_code() . '_languages', $result->get_error_message(), substr($result->get_error_data(), strlen($wp_lang_dir)));
                }
            }
        }
    }
    /** This filter is documented in wp-admin/includes/update-core.php */
    apply_filters('update_feedback', __('Disabling Maintenance mode&#8230;'));
    // Remove maintenance file, we're done with potential site-breaking changes
    $wp_filesystem->delete($maintenance_file);
    // 3.5 -> 3.5+ - an empty twentytwelve directory was created upon upgrade to 3.5 for some users, preventing installation of Twenty Twelve.
    if ('3.5' == $old_wp_version) {
        if (is_dir(WP_CONTENT_DIR . '/themes/twentytwelve') && !file_exists(WP_CONTENT_DIR . '/themes/twentytwelve/style.css')) {
            $wp_filesystem->delete($wp_filesystem->wp_themes_dir() . 'twentytwelve/');
        }
    }
    // Copy New bundled plugins & themes
    // This gives us the ability to install new plugins & themes bundled with future versions of WordPress whilst avoiding the re-install upon upgrade issue.
    // $development_build controls us overwriting bundled themes and plugins when a non-stable release is being updated
    if (!is_wp_error($result) && (!defined('CORE_UPGRADE_SKIP_NEW_BUNDLED') || !CORE_UPGRADE_SKIP_NEW_BUNDLED)) {
        foreach ((array) $_new_bundled_files as $file => $introduced_version) {
            // If a $development_build or if $introduced version is greater than what the site was previously running
            if ($development_build || version_compare($introduced_version, $old_wp_version, '>')) {
                $directory = '/' == $file[strlen($file) - 1];
                list($type, $filename) = explode('/', $file, 2);
                // Check to see if the bundled items exist before attempting to copy them
                if (!$wp_filesystem->exists($from . $distro . 'wp-content/' . $file)) {
                    continue;
                }
                if ('plugins' == $type) {
                    $dest = $wp_filesystem->wp_plugins_dir();
                } elseif ('themes' == $type) {
                    $dest = trailingslashit($wp_filesystem->wp_themes_dir());
                } else {
                    continue;
                }
                if (!$directory) {
                    if (!$development_build && $wp_filesystem->exists($dest . $filename)) {
                        continue;
                    }
                    if (!$wp_filesystem->copy($from . $distro . 'wp-content/' . $file, $dest . $filename, FS_CHMOD_FILE)) {
                        $result = new WP_Error("copy_failed_for_new_bundled_{$type}", __('Could not copy file.'), $dest . $filename);
                    }
                } else {
                    if (!$development_build && $wp_filesystem->is_dir($dest . $filename)) {
                        continue;
                    }
                    $wp_filesystem->mkdir($dest . $filename, FS_CHMOD_DIR);
                    $_result = copy_dir($from . $distro . 'wp-content/' . $file, $dest . $filename);
                    // If a error occurs partway through this final step, keep the error flowing through, but keep process going.
                    if (is_wp_error($_result)) {
                        if (!is_wp_error($result)) {
                            $result = new WP_Error();
                        }
                        $result->add($_result->get_error_code() . "_{$type}", $_result->get_error_message(), substr($_result->get_error_data(), strlen($dest)));
                    }
                }
            }
        }
        //end foreach
    }
    // Handle $result error from the above blocks
    if (is_wp_error($result)) {
        $wp_filesystem->delete($from, true);
        return $result;
    }
    // Remove old files
    foreach ($_old_files as $old_file) {
        $old_file = $to . $old_file;
        if (!$wp_filesystem->exists($old_file)) {
            continue;
        }
        $wp_filesystem->delete($old_file, true);
    }
    // Remove any Genericons example.html's from the filesystem
    _upgrade_422_remove_genericons();
    // Upgrade DB with separate request
    /** This filter is documented in wp-admin/includes/update-core.php */
    apply_filters('update_feedback', __('Upgrading database&#8230;'));
    $db_upgrade_url = admin_url('upgrade.php?step=upgrade_db');
    wp_remote_post($db_upgrade_url, array('timeout' => 60));
    // Clear the cache to prevent an update_option() from saving a stale db_version to the cache
    wp_cache_flush();
    // (Not all cache backends listen to 'flush')
    wp_cache_delete('alloptions', 'options');
    // Remove working directory
    $wp_filesystem->delete($from, true);
    // Force refresh of update information
    if (function_exists('delete_site_transient')) {
        delete_site_transient('update_core');
    } else {
        delete_option('update_core');
    }
    /**
     * Fires after WordPress core has been successfully updated.
     *
     * @since 3.3.0
     *
     * @param string $wp_version The current WordPress version.
     */
    do_action('_core_updated_successfully', $wp_version);
    // Clear the option that blocks auto updates after failures, now that we've been successful.
    if (function_exists('delete_site_option')) {
        delete_site_option('auto_core_update_failed');
    }
    return $wp_version;
}
 function check_files()
 {
     global $wp_version;
     $checksums = get_core_checksums($wp_version);
     if (empty($checksums[$wp_version]) || !is_array($checksums[$wp_version])) {
         return false;
     }
     foreach ($checksums[$wp_version] as $file => $checksum) {
         // Skip files which get updated
         if ('wp-content' == substr($file, 0, 10)) {
             continue;
         }
         if (!file_exists(ABSPATH . $file) || md5_file(ABSPATH . $file) !== $checksum) {
             return false;
         }
     }
     return true;
 }
 /**
  * Compare the disk file checksums agains the expected checksums.
  *
  * @since 3.7.0
  *
  * @return bool True if the checksums match, otherwise false.
  */
 public function check_files()
 {
     global $wp_version, $wp_local_package;
     $checksums = get_core_checksums($wp_version, isset($wp_local_package) ? $wp_local_package : 'en_US');
     if (!is_array($checksums)) {
         return false;
     }
     foreach ($checksums as $file => $checksum) {
         // Skip files which get updated
         if ('wp-content' == substr($file, 0, 10)) {
             continue;
         }
         if (!file_exists(ABSPATH . $file) || md5_file(ABSPATH . $file) !== $checksum) {
             return false;
         }
     }
     return true;
 }
/**
 * Upgrade the core of WordPress.
 *
 * This will create a .maintenance file at the base of the WordPress directory
 * to ensure that people can not access the web site, when the files are being
 * copied to their locations.
 *
 * The files in the {@link $_old_files} list will be removed and the new files
 * copied from the zip file after the database is upgraded.
 *
 * The files in the {@link $_new_bundled_files} list will be added to the installation
 * if the version is greater than or equal to the old version being upgraded.
 *
 * The steps for the upgrader for after the new release is downloaded and
 * unzipped is:
 *   1. Test unzipped location for select files to ensure that unzipped worked.
 *   2. Create the .maintenance file in current WordPress base.
 *   3. Copy new WordPress directory over old WordPress files.
 *   4. Upgrade WordPress to new version.
 *     4.1. Copy all files/folders other than wp-content
 *     4.2. Copy any language files to WP_LANG_DIR (which may differ from WP_CONTENT_DIR
 *     4.3. Copy any new bundled themes/plugins to their respective locations
 *   5. Delete new WordPress directory path.
 *   6. Delete .maintenance file.
 *   7. Remove old files.
 *   8. Delete 'update_core' option.
 *
 * There are several areas of failure. For instance if PHP times out before step
 * 6, then you will not be able to access any portion of your site. Also, since
 * the upgrade will not continue where it left off, you will not be able to
 * automatically remove old files and remove the 'update_core' option. This
 * isn't that bad.
 *
 * If the copy of the new WordPress over the old fails, then the worse is that
 * the new WordPress directory will remain.
 *
 * If it is assumed that every file will be copied over, including plugins and
 * themes, then if you edit the default theme, you should rename it, so that
 * your changes remain.
 *
 * @since 2.7.0
 *
 * @param string $from New release unzipped path.
 * @param string $to Path to old WordPress installation.
 * @return WP_Error|null WP_Error on failure, null on success.
 */
function update_core($from, $to)
{
    global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;
    @set_time_limit(300);
    // Sanity check the unzipped distribution
    apply_filters('update_feedback', __('Verifying the unpacked files&#8230;'));
    $distro = '';
    $roots = array('/wordpress/', '/wordpress-mu/');
    foreach ($roots as $root) {
        if ($wp_filesystem->exists($from . $root . 'readme.html') && $wp_filesystem->exists($from . $root . 'wp-includes/version.php')) {
            $distro = $root;
            break;
        }
    }
    if (!$distro) {
        $wp_filesystem->delete($from, true);
        return new WP_Error('insane_distro', __('The update could not be unpacked'));
    }
    // Import $wp_version, $required_php_version, and $required_mysql_version from the new version
    // $wp_filesystem->wp_content_dir() returned unslashed pre-2.8
    $versions_file = trailingslashit($wp_filesystem->wp_content_dir()) . 'upgrade/version-current.php';
    if (!$wp_filesystem->copy($from . $distro . 'wp-includes/version.php', $versions_file)) {
        $wp_filesystem->delete($from, true);
        return new WP_Error('copy_failed', __('Could not copy file.'));
    }
    $wp_filesystem->chmod($versions_file, FS_CHMOD_FILE);
    require WP_CONTENT_DIR . '/upgrade/version-current.php';
    $wp_filesystem->delete($versions_file);
    $php_version = phpversion();
    $mysql_version = $wpdb->db_version();
    $old_wp_version = $GLOBALS['wp_version'];
    // The version of WordPress we're updating from
    $development_build = false !== strpos($old_wp_version . $wp_version, '-');
    // a dash in the version indicates a Development release
    $php_compat = version_compare($php_version, $required_php_version, '>=');
    if (file_exists(WP_CONTENT_DIR . '/db.php') && empty($wpdb->is_mysql)) {
        $mysql_compat = true;
    } else {
        $mysql_compat = version_compare($mysql_version, $required_mysql_version, '>=');
    }
    if (!$mysql_compat || !$php_compat) {
        $wp_filesystem->delete($from, true);
    }
    if (!$mysql_compat && !$php_compat) {
        return new WP_Error('php_mysql_not_compatible', sprintf(__('The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher and MySQL version %3$s or higher. You are running PHP version %4$s and MySQL version %5$s.'), $wp_version, $required_php_version, $required_mysql_version, $php_version, $mysql_version));
    } elseif (!$php_compat) {
        return new WP_Error('php_not_compatible', sprintf(__('The update cannot be installed because WordPress %1$s requires PHP version %2$s or higher. You are running version %3$s.'), $wp_version, $required_php_version, $php_version));
    } elseif (!$mysql_compat) {
        return new WP_Error('mysql_not_compatible', sprintf(__('The update cannot be installed because WordPress %1$s requires MySQL version %2$s or higher. You are running version %3$s.'), $wp_version, $required_mysql_version, $mysql_version));
    }
    apply_filters('update_feedback', __('Preparing to install the latest version&#8230;'));
    // Don't copy wp-content, we'll deal with that below
    $skip = array('wp-content');
    // Check to see which files don't really need updating - only available for 3.7 and higher
    if (function_exists('get_core_checksums')) {
        $checksums = get_core_checksums($wp_version);
        if (!empty($checksums[$wp_version]) && is_array($checksums[$wp_version])) {
            foreach ($checksums[$wp_version] as $file => $checksum) {
                if ('wp-content' == substr($file, 0, 10)) {
                    continue;
                }
                if (file_exists(ABSPATH . $file) && md5_file(ABSPATH . $file) === $checksum) {
                    $skip[] = $file;
                }
            }
        }
    }
    apply_filters('update_feedback', __('Enabling Maintenance mode&#8230;'));
    // Create maintenance file to signal that we are upgrading
    $maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
    $maintenance_file = $to . '.maintenance';
    $wp_filesystem->delete($maintenance_file);
    $wp_filesystem->put_contents($maintenance_file, $maintenance_string, FS_CHMOD_FILE);
    apply_filters('update_feedback', __('Copying the required files&#8230;'));
    // Copy new versions of WP files into place.
    $result = _copy_dir($from . $distro, $to, $skip);
    // Check to make sure everything copied correctly, ignoring the contents of wp-content
    $skip = array('wp-content');
    $failed = array();
    if (!empty($checksums[$wp_version]) && is_array($checksums[$wp_version])) {
        foreach ($checksums[$wp_version] as $file => $checksum) {
            if (0 === strpos($file, 'wp-content')) {
                continue;
            }
            if (md5_file(ABSPATH . $file) == $checksum) {
                $skip[] = $file;
            } else {
                $failed[] = $file;
            }
        }
    }
    // Some files didn't copy properly
    if (!empty($failed)) {
        $total_size = 0;
        // Find the local version of the working directory
        $working_dir_local = str_replace(trailingslashit($wp_filesystem->wp_content_dir()), trailingslashit(WP_CONTENT_DIR), $from . $distro);
        foreach ($failed as $file) {
            $total_size += filesize($working_dir_local . '/' . $file);
        }
        // If we don't have enough free space, it isn't worth trying again
        if ($total_size >= disk_free_space(ABSPATH)) {
            $result = new WP_Error('disk_full', __('There is not enough free disk space to complete the update.'), $to);
        } else {
            $result = _copy_dir($from . $distro, $to, $skip);
        }
    }
    // Custom Content Directory needs updating now.
    // Copy Languages
    if (!is_wp_error($result) && $wp_filesystem->is_dir($from . $distro . 'wp-content/languages')) {
        if (WP_LANG_DIR != ABSPATH . WPINC . '/languages' || @is_dir(WP_LANG_DIR)) {
            $lang_dir = WP_LANG_DIR;
        } else {
            $lang_dir = WP_CONTENT_DIR . '/languages';
        }
        if (!@is_dir($lang_dir) && 0 === strpos($lang_dir, ABSPATH)) {
            // Check the language directory exists first
            $wp_filesystem->mkdir($to . str_replace(ABSPATH, '', $lang_dir), FS_CHMOD_DIR);
            // If it's within the ABSPATH we can handle it here, otherwise they're out of luck.
            clearstatcache();
            // for FTP, Need to clear the stat cache
        }
        if (@is_dir($lang_dir)) {
            $wp_lang_dir = $wp_filesystem->find_folder($lang_dir);
            if ($wp_lang_dir) {
                $result = copy_dir($from . $distro . 'wp-content/languages/', $wp_lang_dir);
            }
        }
    }
    // 3.5 -> 3.5+ - an empty twentytwelve directory was created upon upgrade to 3.5 for some users, preventing installation of Twenty Twelve.
    if ('3.5' == $old_wp_version) {
        if (is_dir(WP_CONTENT_DIR . '/themes/twentytwelve') && !file_exists(WP_CONTENT_DIR . '/themes/twentytwelve/style.css')) {
            $wp_filesystem->delete($wp_filesystem->wp_themes_dir() . 'twentytwelve/');
        }
    }
    // Copy New bundled plugins & themes
    // This gives us the ability to install new plugins & themes bundled with future versions of WordPress whilst avoiding the re-install upon upgrade issue.
    // $development_build controls us overwriting bundled themes and plugins when a non-stable release is being updated
    if (!is_wp_error($result) && (!defined('CORE_UPGRADE_SKIP_NEW_BUNDLED') || !CORE_UPGRADE_SKIP_NEW_BUNDLED)) {
        foreach ((array) $_new_bundled_files as $file => $introduced_version) {
            // If a $development_build or if $introduced version is greater than what the site was previously running
            if ($development_build || version_compare($introduced_version, $old_wp_version, '>')) {
                $directory = '/' == $file[strlen($file) - 1];
                list($type, $filename) = explode('/', $file, 2);
                // Check to see if the bundled items exist before attempting to copy them
                if (!$wp_filesystem->exists($from . $distro . 'wp-content/' . $file)) {
                    continue;
                }
                if ('plugins' == $type) {
                    $dest = $wp_filesystem->wp_plugins_dir();
                } elseif ('themes' == $type) {
                    $dest = trailingslashit($wp_filesystem->wp_themes_dir());
                } else {
                    continue;
                }
                if (!$directory) {
                    if (!$development_build && $wp_filesystem->exists($dest . $filename)) {
                        continue;
                    }
                    if (!$wp_filesystem->copy($from . $distro . 'wp-content/' . $file, $dest . $filename, FS_CHMOD_FILE)) {
                        $result = new WP_Error('copy_failed', __('Could not copy file.'), $dest . $filename);
                    }
                } else {
                    if (!$development_build && $wp_filesystem->is_dir($dest . $filename)) {
                        continue;
                    }
                    $wp_filesystem->mkdir($dest . $filename, FS_CHMOD_DIR);
                    $_result = copy_dir($from . $distro . 'wp-content/' . $file, $dest . $filename);
                    if (is_wp_error($_result)) {
                        //If a error occurs partway through this final step, keep the error flowing through, but keep process going.
                        $result = $_result;
                    }
                }
            }
        }
        //end foreach
    }
    // Handle $result error from the above blocks
    if (is_wp_error($result)) {
        $wp_filesystem->delete($maintenance_file);
        $wp_filesystem->delete($from, true);
        return $result;
    }
    // Remove old files
    foreach ($_old_files as $old_file) {
        $old_file = $to . $old_file;
        if (!$wp_filesystem->exists($old_file)) {
            continue;
        }
        $wp_filesystem->delete($old_file, true);
    }
    // Upgrade DB with separate request
    apply_filters('update_feedback', __('Upgrading database&#8230;'));
    $db_upgrade_url = admin_url('upgrade.php?step=upgrade_db');
    wp_remote_post($db_upgrade_url, array('timeout' => 60));
    // Remove working directory
    $wp_filesystem->delete($from, true);
    // Force refresh of update information
    if (function_exists('delete_site_transient')) {
        delete_site_transient('update_core');
    } else {
        delete_option('update_core');
    }
    apply_filters('update_feedback', __('Disabling Maintenance mode&#8230;'));
    // Remove maintenance file, we're done.
    $wp_filesystem->delete($maintenance_file);
    // If we made it this far:
    do_action('_core_updated_successfully', $wp_version);
    return $wp_version;
}