Be a party-pooper; No more Akismet Dancing upon upgrade; Respect custom WP_CONTENT_DIR for bundled plugins/theme installation; Respect custom WP_CONTENT_DIR/WP_LANG_DIR for Language files when upgrading; Standardise WP_Filesystem path method returns (They're trailing slash'd). Adds an exclusion list to copy_dir() as well as WP_Filesystem_Base::wp_lang_dir(). See #14484 See #11495

git-svn-id: https://develop.svn.wordpress.org/trunk@17576 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Dion Hulse 2011-03-31 13:28:36 +00:00
parent 746173b4b8
commit 20603ca19c
3 changed files with 110 additions and 8 deletions

View File

@ -82,7 +82,18 @@ class WP_Filesystem_Base {
* @return string The location of the remote path.
*/
function wp_themes_dir() {
return $this->wp_content_dir() . '/themes';
return $this->wp_content_dir() . 'themes/';
}
/**
* Returns the path on the remote filesystem of WP_LANG_DIR
*
* @since 3.2
* @access public
*
* @return string The location of the remote path.
*/
function wp_lang_dir() {
return $this->find_folder(WP_LANG_DIR);
}
/**

View File

@ -716,9 +716,10 @@ function _unzip_file_pclzip($file, $to, $needed_dirs = array()) {
*
* @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) {
function copy_dir($from, $to, $skip_list = array() ) {
global $wp_filesystem;
$dirlist = $wp_filesystem->dirlist($from);
@ -726,7 +727,18 @@ function copy_dir($from, $to) {
$from = trailingslashit($from);
$to = trailingslashit($to);
$skip_regex = '';
foreach ( (array)$skip_list as $key => $skip_file )
$skip_regex .= preg_quote($skip_file, '!') . '|';
if ( !empty($skip_regex) )
$skip_regex = '!(' . rtrim($skip_regex, '|') . ')$!i';
foreach ( (array) $dirlist as $filename => $fileinfo ) {
if ( !empty($skip_regex) )
if ( preg_match($skip_regex, $from . $filename) )
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.
@ -739,7 +751,7 @@ function copy_dir($from, $to) {
if ( !$wp_filesystem->mkdir($to . $filename, FS_CHMOD_DIR) )
return new WP_Error('mkdir_failed', __('Could not create directory.'), $to . $filename);
}
$result = copy_dir($from . $filename, $to . $filename);
$result = copy_dir($from . $filename, $to . $filename, $skip_list);
if ( is_wp_error($result) )
return $result;
}

View File

@ -245,6 +245,30 @@ $_old_files = array(
'wp-includes/classes.php',
);
/**
* Stores new files in wp-content to copy
*
* The contents of this array indicate any new bundled plugins/themes which
* should be installed with the WordPress Upgrade. These items will not be
* re-installed in future upgrades, this behaviour is controlled by the
* introduced version present here being older than the current installed version.
*
* The content of this array should follow the following format:
* Filename (relative to wp-content) => Introduced version
* Directories should be noted by suffixing it with a trailing slash (/)
*
* @since 3.2
* @global array $_new_bundled_files
* @var array
* @name $_new_bundled_files
*/
global $_new_bundled_files;
$_new_bundled_files = array(
'plugins/akismet/' => '2.0',
'themes/twentyten/' => '3.2',
);
/**
* Upgrade the core of WordPress.
*
@ -255,12 +279,18 @@ $_old_files = array(
* 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.
@ -286,7 +316,7 @@ $_old_files = array(
* @return WP_Error|null WP_Error on failure, null on success.
*/
function update_core($from, $to) {
global $wp_filesystem, $_old_files, $wpdb;
global $wp_filesystem, $_old_files, $_new_bundled_files, $wpdb;
@set_time_limit( 300 );
@ -311,10 +341,10 @@ function update_core($from, $to) {
// Sanity check the unzipped distribution
apply_filters('update_feedback', __('Verifying the unpacked files…'));
$distro = '';
$roots = array( '/wordpress', '/wordpress-mu' );
$roots = array( '/wordpress/', '/wordpress-mu/' );
foreach( $roots as $root ) {
if ( $wp_filesystem->exists($from . $root . '/wp-settings.php') && $wp_filesystem->exists($from . $root . '/wp-admin/admin.php') &&
$wp_filesystem->exists($from . $root . '/wp-includes/functions.php') ) {
if ( $wp_filesystem->exists($from . $root . 'wp-settings.php') && $wp_filesystem->exists($from . $root . 'wp-admin/admin.php') &&
$wp_filesystem->exists($from . $root . 'wp-includes/functions.php') ) {
$distro = $root;
break;
}
@ -333,7 +363,56 @@ function update_core($from, $to) {
$wp_filesystem->put_contents($maintenance_file, $maintenance_string, FS_CHMOD_FILE);
// Copy new versions of WP files into place.
$result = copy_dir($from . $distro, $to);
$result = copy_dir($from . $distro, $to, array('wp-content') );
// Custom Content Directory needs updating now.
// Copy Languages
if ( !is_wp_error($result) && $wp_filesystem->is_dir($from . $distro . 'wp-content/languages') ) {
if ( !@is_dir(WP_LANG_DIR) && 0 === strpos(WP_LANG_DIR, ABSPATH) ) { // Check the language directory exists first
$wp_filesystem->mkdir($to . str_replace(WP_LANG_DIR, ABSPATH, ''), 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(WP_LANG_DIR) ) {
$wp_lang_dir = $wp_filesystem->wp_lang_dir();
$result = copy_dir($from . $distro . 'wp-content/languages/', $wp_lang_dir);
}
}
// 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.
if ( !is_wp_error($result) && ( ! defined('CORE_UPGRADE_SKIP_NEW_BUNDLED') || ! CORE_UPGRADE_SKIP_NEW_BUNDLED ) ) {
$old_version = $GLOBALS['wp_version']; // $wp_version in local scope == new version
foreach ( (array) $_new_bundled_files as $file => $introduced_version ) {
// If $introduced version is greater than what the site was previously running
if ( version_compare($introduced_version, $old_version, '>') ) {
$directory = ('/' == $file[ strlen($file)-1 ]);
list($type, $filename) = explode('/', $file, 2);
if ( 'plugins' == $type )
$dest = $wp_filesystem->wp_plugins_dir();
elseif ( 'themes' == $type )
$dest = $wp_filesystem->wp_themes_dir();
if ( ! $directory ) {
if ( $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 ( $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);