dirlist( $args['source'] ) );
$remote_destination = $wp_filesystem->find_folder( $args['destination'] );
// Locate which directory to copy to the new folder, This is based on the actual folder holding the files.
if ( 1 === count( $source_files ) && $wp_filesystem->is_dir( trailingslashit( $args['source'] ) . $source_files[0] . '/' ) ) { // Only one folder? Then we want its contents.
$destination = trailingslashit( $remote_destination ) . trailingslashit( $source_files[0] );
} elseif ( 0 === count( $source_files ) ) {
// Looks like an empty zip, we'll let the default code handle this.
return parent::install_package( $args );
} else { // It's only a single file, the upgrader will use the folder name of this file as the destination folder. Folder name is based on zip filename.
$destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $args['source'] ) );
}
if ( is_dir( $destination ) && file_exists( "$destination/style.css" ) ) {
// This is an upgrade, clear the destination.
$args['clear_destination'] = true;
// Switch template strings to use upgrade terminology rather than install terminology.
$this->upgrade_strings();
// Replace default remove_old string to make the messages more meaningful.
$this->strings['installing_package'] = __( 'Upgrading the theme…', 'easy-theme-and-plugin-upgrades' );
$this->strings['remove_old'] = __( 'Backing up the old version of the theme…', 'easy-theme-and-plugin-upgrades' );
}
return parent::install_package( $args );
}
public function clear_destination( $destination ) {
global $wp_filesystem;
if ( ! is_dir( $destination ) || ! file_exists( "$destination/style.css" ) ) {
// This is an installation not an upgrade.
return parent::clear_destination( $destination );
}
$backup_url = $this->create_backup( $destination );
if ( ! is_wp_error( $backup_url ) ) {
/* translators: 1: theme zip URL */
$this->skin->feedback( sprintf( __( 'A backup zip file of the old theme version can be downloaded here.', 'easy-theme-and-plugin-upgrades' ), $backup_url ) );
// Restore default strings and display the original remove_old message.
$this->upgrade_strings();
$this->skin->feedback( 'remove_old' );
return parent::clear_destination( $destination );
}
$this->skin->error( $backup_url );
$this->skin->feedback( __( 'Moving the old version of the theme to a new directory…', 'easy-theme-and-plugin-upgrades' ) );
$headers = array(
'version' => 'Version',
);
$data = get_file_data( "$destination/style.css", $headers );
$new_name = basename( $destination ) . "-{$data['version']}";
$directory = dirname( $destination );
for ( $x = 0; $x < 20; $x++ ) {
$test_name = $new_name . '-' . $this->get_random_characters( 10, 20 );
if ( ! is_dir( "$directory/$test_name" ) ) {
$new_name = $test_name;
break;
}
}
if ( is_dir( "$directory/$new_name" ) ) {
// We gave it our best effort. Time to give up on the idea of having a backup.
$this->skin->error( __( 'Unable to find a new directory name to move the old version of the theme to. No backup will be created.', 'easy-theme-and-plugin-upgrades' ) );
} else {
$result = $wp_filesystem->move( $destination, "$directory/$new_name" );
if ( $result ) {
/* translators: 1: new theme directory name */
$this->skin->feedback( sprintf( __( 'Moved the old version of the theme to a new theme directory named %1$s. This directory should be backed up and removed from the site.', 'easy-theme-and-plugin-upgrades' ), "$new_name" ) );
} else {
$this->skin->error( __( 'Unable to move the old version of the theme to a new directory. No backup will be created.', 'easy-theme-and-plugin-upgrades' ) );
}
}
// Restore default strings and display the original remove_old message.
$this->upgrade_strings();
$this->skin->feedback( 'remove_old' );
return parent::clear_destination( $destination );
}
private function create_backup( $directory ) {
require_once( ABSPATH . 'wp-admin/includes/file.php' );
$wp_upload_dir = wp_upload_dir();
$zip_path = $wp_upload_dir['path'];
$zip_url = $wp_upload_dir['url'];
if ( ! is_dir( $zip_path ) ) {
return new WP_Error( 'caj-etpu-cannot-backup-no-destination-path', __( 'A theme backup can not be created since a destination path for the backup file could not be found.', 'easy-theme-and-plugin-upgrades' ) );
}
$headers = array(
'name' => 'Theme Name',
'version' => 'Version',
);
$data = get_file_data( "$directory/style.css", $headers );
$rand_string = $this->get_random_characters( 10, 20 );
$zip_file = basename( $directory ) . "-{$data['version']}-$rand_string.zip";
// Reduce the chance that a timeout will occur while creating the zip file.
@set_time_limit( 600 );
// Attempt to increase memory limits.
$this->set_minimum_memory_limit( '256M' );
$zip_path .= "/$zip_file";
$zip_url .= "/$zip_file";
require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
$archive = new PclZip( $zip_path );
$zip_result = $archive->create( $directory, PCLZIP_OPT_REMOVE_PATH, dirname( $directory ) );
if ( 0 === $zip_result ) {
/* translators: 1: zip error details */
return new WP_Error( 'caj-etpu-cannot-backup-zip-failed', sprintf( __( 'A theme backup can not be created as creation of the zip file failed with the following error: %1$s', 'easy-theme-and-plugin-upgrades' ), $archive->errorInfo( true ) ) );
}
$attachment = array(
'post_mime_type' => 'application/zip',
'guid' => $zip_url,
/* translators: 1: theme name, 2: theme version */
'post_title' => sprintf( __( 'Theme Backup - %1$s - %2$s', 'easy-theme-and-plugin-upgrades' ), $data['name'], $data['version'] ),
'post_content' => '',
);
$id = wp_insert_attachment( $attachment, $zip_path );
if ( ! is_wp_error( $id ) ) {
wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $zip_path ) );
}
return $zip_url;
}
private function get_random_characters( $min_length, $max_length ) {
$characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$rand_string = '';
$length = rand( $min_length, $max_length );
for ( $count = 0; $count < $length; $count++ ) {
$rand_string .= $characters[ rand( 0, strlen( $characters ) - 1 ) ];
}
return $rand_string;
}
function set_minimum_memory_limit( $new_memory_limit ) {
$memory_limit = @ini_get( 'memory_limit' );
if ( $memory_limit > -1 ) {
$unit = strtolower( substr( $memory_limit, -1 ) );
$new_unit = strtolower( substr( $new_memory_limit, -1 ) );
$memory_limit = intval( $memory_limit );
$new_memory_limit = intval( $new_memory_limit );
if ( 'm' == $unit ) {
$memory_limit *= 1048576;
} elseif ( 'g' == $unit ) {
$memory_limit *= 1073741824;
} elseif ( 'k' == $unit ) {
$memory_limit *= 1024;
}
if ( 'm' == $new_unit ) {
$new_memory_limit *= 1048576;
} else if ( 'g' == $new_unit ) {
$new_memory_limit *= 1073741824;
} else if ( 'k' == $new_unit ) {
$new_memory_limit *= 1024;
}
if ( (int) $memory_limit < (int) $new_memory_limit ) {
@ini_set( 'memory_limit', $new_memory_limit );
}
}
}
}