Title: dkomander's Replies | WordPress.org

---

# dkomander

  [  ](https://wordpress.org/support/users/dkomander/)

 *   [Profile](https://wordpress.org/support/users/dkomander/)
 *   [Topics Started](https://wordpress.org/support/users/dkomander/topics/)
 *   [Replies Created](https://wordpress.org/support/users/dkomander/replies/)
 *   [Reviews Written](https://wordpress.org/support/users/dkomander/reviews/)
 *   [Topics Replied To](https://wordpress.org/support/users/dkomander/replied-to/)
 *   [Engagements](https://wordpress.org/support/users/dkomander/engagements/)
 *   [Favorites](https://wordpress.org/support/users/dkomander/favorites/)

 Search replies:

## Forum Replies Created

Viewing 5 replies - 1 through 5 (of 5 total)

 *   Forum: [Plugins](https://wordpress.org/support/forum/plugins-and-hacks/)
    In
   reply to: [[Easy Updates Manager] automatic update not working, even after all the config changes](https://wordpress.org/support/topic/automatic-update-not-working-even-after-all-the-config-changes/)
 *  Thread Starter [dkomander](https://wordpress.org/support/users/dkomander/)
 * (@dkomander)
 * [9 years, 8 months ago](https://wordpress.org/support/topic/automatic-update-not-working-even-after-all-the-config-changes/#post-7670759)
 * Hi Matthew,
 * first of all, sorry for the late reply (have been busy for quite while) and thank
   you for the suggestions!
 * I tried your solutions (force update & disabling plugins) but unfortunately, 
   it did not change anything. 🙁
 * I am convinced it must be either myself or the machines that i create but finding
   that out is the hard part.
 * However, i also tried installing completely new centos 7 machines not only in
   aws, but also in our vsphere with the normal image you can download you get from
   centos.
 * Aside from deactivating firewalld, selinux and installing basic lamp construction
   and wordpress, nothing else was done on these machines.
 * And still it refuses to work. So i must still be missing something… :-/
 * As you noticed, i searched for everything in the wordpress-configuration, that
   is DISABLING my auto updates but could not find any.
 * The manual update mechanic itself works smoothly, as soon as i hit “update core”
   or “update plugin” it just updates and works normally after that. It just won’t
   auto update, even if i let the machines stay on for weeks.
 * Maybe someone can replicate this also with a completely new centos 7 machine,
   installed with basic lamp and wordpress (older version, to test auto update),
   and also deactivate firewalld and selinux (or configure it so let these apps 
   communicate). It would help greatly. 🙂
 * Best Regards
 * David
 *   Forum: [Fixing WordPress](https://wordpress.org/support/forum/how-to-and-troubleshooting/)
   
   In reply to: [auto update not working for wordpress 4.5.3](https://wordpress.org/support/topic/auto-update-not-working-for-wordpress-453/)
 *  Thread Starter [dkomander](https://wordpress.org/support/users/dkomander/)
 * (@dkomander)
 * [9 years, 9 months ago](https://wordpress.org/support/topic/auto-update-not-working-for-wordpress-453/#post-7647647)
 * Hi James,
 * thank you and sadly, it was not the solution either. :-/
 * OK, i opened a thread in the plugins section and hope to get a solution there.
   Thanks so far for the assistance!
 * [https://wordpress.org/support/topic/automatic-update-not-working-even-after-all-the-config-changes?replies=1#post-8761174](https://wordpress.org/support/topic/automatic-update-not-working-even-after-all-the-config-changes?replies=1#post-8761174)
 *   Forum: [Fixing WordPress](https://wordpress.org/support/forum/how-to-and-troubleshooting/)
   
   In reply to: [auto update not working for wordpress 4.5.3](https://wordpress.org/support/topic/auto-update-not-working-for-wordpress-453/)
 *  Thread Starter [dkomander](https://wordpress.org/support/users/dkomander/)
 * (@dkomander)
 * [9 years, 9 months ago](https://wordpress.org/support/topic/auto-update-not-working-for-wordpress-453/#post-7647642)
 * Hi James,
 * alright, i tried it on a completely new machine with centos 7 64-bit. I installed
   httpd, mysql, php, and download wordpress in version 4.5.0 (not the newest version,
   in order to test auto-update).
 * I setup basic wordpress:
 * – untar in /var/www/html
    – copy wp-config-sample into wp-config.php – enter 
   database information – enter [http://url-of-server/wordpress](http://url-of-server/wordpress)–
   setup basic wordpress site until i could login into dashboard
 * then i noticed of course that the system tells me to update one plugin and wordpress
   itself to 4.5.3.
 * Then i installed the easy update manager and set anything to “enable”. I also
   activated logs.
 * I restarted the whole server and waited for a full day.
 * However, still no update. :-/
 * Is there a hidden cron job that i need to activate / enable, so auto-updates 
   can occur?
 * Even with the new installation on a completely new machine with basic centos 
   7 core, it still does not auto-update. :-/
 * (manual update is still working without problems, when i click manually on “update
   wordpress” and “update plugin”)
 * Any suggestions?
 *   Forum: [Fixing WordPress](https://wordpress.org/support/forum/how-to-and-troubleshooting/)
   
   In reply to: [auto update not working for wordpress 4.5.3](https://wordpress.org/support/topic/auto-update-not-working-for-wordpress-453/)
 *  Thread Starter [dkomander](https://wordpress.org/support/users/dkomander/)
 * (@dkomander)
 * [9 years, 9 months ago](https://wordpress.org/support/topic/auto-update-not-working-for-wordpress-453/#post-7647618)
 * Hi James,
 * i did a grep on these words, but i have not set them. I found out, that there
   is a file “class-wp-upgrader.php”, maybe this is the culprit?
 *     ```
       <?php
       /**
        * Upgrade API: WP_Upgrader, Plugin_Upgrader, Theme_Upgrader, Language_Pack_Upgrader,
        * Core_Upgrader, File_Upload_Upgrader, and WP_Automatic_Updater classes
        *
        * This set of classes are designed to be used to upgrade/install a local set of files
        * on the filesystem via the Filesystem Abstraction classes.
        *
        * @package WordPress
        * @subpackage Upgrader
        * @since 2.8.0
        */
   
       require ABSPATH . 'wp-admin/includes/class-wp-upgrader-skins.php';
   
       /**
        * Core class used for upgrading/installing a local set of files via
        * the Filesystem Abstraction classes from a Zip file.
        *
        * @since 2.8.0
        */
       class WP_Upgrader {
   
       	/**
       	 * The error/notification strings used to update the user on the progress.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 * @var string $strings
       	 */
       	public $strings = array();
   
       	/**
       	 * The upgrader skin being used.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 * @var WP_Upgrader_Skin $skin
       	 */
       	public $skin = null;
   
       	/**
       	 * The result of the installation.
       	 *
       	 * This is set by {@see WP_Upgrader::install_package()}, only when the package is installed
       	 * successfully. It will then be an array, unless a {@see WP_Error} is returned by the
       	 * {@see 'upgrader_post_install'} filter. In that case, the <code>WP_Error</code> will be assigned to
       	 * it.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @var WP_Error|array $result {
       	 *      @type string $source             The full path to the source the files were installed from.
       	 *      @type string $source_files       List of all the files in the source directory.
       	 *      @type string $destination        The full path to the install destination folder.
       	 *      @type string $destination_name   The name of the destination folder, or empty if <code>$destination</code>
       	 *                                       and <code>$local_destination</code> are the same.
       	 *      @type string $local_destination  The full local path to the destination folder. This is usually
       	 *                                       the same as <code>$destination</code>.
       	 *      @type string $remote_destination The full remote path to the destination folder
       	 *                                       (i.e., from <code>$wp_filesystem</code>).
       	 *      @type bool   $clear_destination  Whether the destination folder was cleared.
       	 * }
       	 */
       	public $result = array();
   
       	/**
       	 * The total number of updates being performed.
       	 *
       	 * Set by the bulk update methods.
       	 *
       	 * @since 3.0.0
       	 * @access public
       	 * @var int $update_count
       	 */
       	public $update_count = 0;
   
       	/**
       	 * The current update if multiple updates are being performed.
       	 *
       	 * Used by the bulk update methods, and incremented for each update.
       	 *
       	 * @since 3.0.0
       	 * @access public
       	 * @var int
       	 */
       	public $update_current = 0;
   
       	/**
       	 * Construct the upgrader with a skin.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @param WP_Upgrader_Skin $skin The upgrader skin to use. Default is a {@see WP_Upgrader_Skin}
       	 *                               instance.
       	 */
       	public function __construct( $skin = null ) {
       		if ( null == $skin )
       			$this->skin = new WP_Upgrader_Skin();
       		else
       			$this->skin = $skin;
       	}
   
       	/**
       	 * Initialize the upgrader.
       	 *
       	 * This will set the relationship between the skin being used and this upgrader,
       	 * and also add the generic strings to <code>WP_Upgrader::$strings</code>.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 */
       	public function init() {
       		$this->skin->set_upgrader($this);
       		$this->generic_strings();
       	}
   
       	/**
       	 * Add the generic strings to WP_Upgrader::$strings.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 */
       	public function generic_strings() {
       		$this->strings['bad_request'] = __('Invalid Data provided.');
       		$this->strings['fs_unavailable'] = __('Could not access filesystem.');
       		$this->strings['fs_error'] = __('Filesystem error.');
       		$this->strings['fs_no_root_dir'] = __('Unable to locate WordPress Root directory.');
       		$this->strings['fs_no_content_dir'] = __('Unable to locate WordPress Content directory (wp-content).');
       		$this->strings['fs_no_plugins_dir'] = __('Unable to locate WordPress Plugin directory.');
       		$this->strings['fs_no_themes_dir'] = __('Unable to locate WordPress Theme directory.');
       		/* translators: %s: directory name */
       		$this->strings['fs_no_folder'] = __('Unable to locate needed folder (%s).');
   
       		$this->strings['download_failed'] = __('Download failed.');
       		$this->strings['installing_package'] = __('Installing the latest version…');
       		$this->strings['no_files'] = __('The package contains no files.');
       		$this->strings['folder_exists'] = __('Destination folder already exists.');
       		$this->strings['mkdir_failed'] = __('Could not create directory.');
       		$this->strings['incompatible_archive'] = __('The package could not be installed.');
       		$this->strings['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.' );
   
       		$this->strings['maintenance_start'] = __('Enabling Maintenance mode…');
       		$this->strings['maintenance_end'] = __('Disabling Maintenance mode…');
       	}
   
       	/**
       	 * Connect to the filesystem.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @global WP_Filesystem_Base $wp_filesystem Subclass
       	 *
       	 * @param array $directories                  Optional. A list of directories. If any of these do
       	 *                                            not exist, a {@see WP_Error} object will be returned.
       	 *                                            Default empty array.
       	 * @param bool  $allow_relaxed_file_ownership Whether to allow relaxed file ownership.
       	 *                                            Default false.
       	 * @return bool|WP_Error True if able to connect, false or a {@see WP_Error} otherwise.
       	 */
       	public function fs_connect( $directories = array(), $allow_relaxed_file_ownership = false ) {
       		global $wp_filesystem;
   
       		if ( false === ( $credentials = $this->skin->request_filesystem_credentials( false, $directories[0], $allow_relaxed_file_ownership ) ) ) {
       			return false;
       		}
   
       		if ( ! WP_Filesystem( $credentials, $directories[0], $allow_relaxed_file_ownership ) ) {
       			$error = true;
       			if ( is_object($wp_filesystem) && $wp_filesystem->errors->get_error_code() )
       				$error = $wp_filesystem->errors;
       			// Failed to connect, Error and request again
       			$this->skin->request_filesystem_credentials( $error, $directories[0], $allow_relaxed_file_ownership );
       			return false;
       		}
   
       		if ( ! is_object($wp_filesystem) )
       			return new WP_Error('fs_unavailable', $this->strings['fs_unavailable'] );
   
       		if ( is_wp_error($wp_filesystem->errors) && $wp_filesystem->errors->get_error_code() )
       			return new WP_Error('fs_error', $this->strings['fs_error'], $wp_filesystem->errors);
   
       		foreach ( (array)$directories as $dir ) {
       			switch ( $dir ) {
       				case ABSPATH:
       					if ( ! $wp_filesystem->abspath() )
       						return new WP_Error('fs_no_root_dir', $this->strings['fs_no_root_dir']);
       					break;
       				case WP_CONTENT_DIR:
       					if ( ! $wp_filesystem->wp_content_dir() )
       						return new WP_Error('fs_no_content_dir', $this->strings['fs_no_content_dir']);
       					break;
       				case WP_PLUGIN_DIR:
       					if ( ! $wp_filesystem->wp_plugins_dir() )
       						return new WP_Error('fs_no_plugins_dir', $this->strings['fs_no_plugins_dir']);
       					break;
       				case get_theme_root():
       					if ( ! $wp_filesystem->wp_themes_dir() )
       						return new WP_Error('fs_no_themes_dir', $this->strings['fs_no_themes_dir']);
       					break;
       				default:
       					if ( ! $wp_filesystem->find_folder($dir) )
       						return new WP_Error( 'fs_no_folder', sprintf( $this->strings['fs_no_folder'], esc_html( basename( $dir ) ) ) );
       					break;
       			}
       		}
       		return true;
       	} //end fs_connect();
   
       	/**
       	 * Download a package.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @param string $package The URI of the package. If this is the full path to an
       	 *                        existing local file, it will be returned untouched.
       	 * @return string|WP_Error The full path to the downloaded package file, or a {@see WP_Error} object.
       	 */
       	public function download_package( $package ) {
   
       		/**
       		 * Filter whether to return the package.
       		 *
       		 * @since 3.7.0
       		 * @access public
       		 *
       		 * @param bool        $reply   Whether to bail without returning the package.
       		 *                             Default false.
       		 * @param string      $package The package file name.
       		 * @param WP_Upgrader $this    The WP_Upgrader instance.
       		 */
       		$reply = apply_filters( 'upgrader_pre_download', false, $package, $this );
       		if ( false !== $reply )
       			return $reply;
   
       		if ( ! preg_match('!^(http|https|ftp)://!i', $package) && file_exists($package) ) //Local file or remote?
       			return $package; //must be a local file..
   
       		if ( empty($package) )
       			return new WP_Error('no_package', $this->strings['no_package']);
   
       		$this->skin->feedback('downloading_package', $package);
   
       		$download_file = download_url($package);
   
       		if ( is_wp_error($download_file) )
       			return new WP_Error('download_failed', $this->strings['download_failed'], $download_file->get_error_message());
   
       		return $download_file;
       	}
   
       	/**
       	 * Unpack a compressed package file.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @global WP_Filesystem_Base $wp_filesystem Subclass
       	 *
       	 * @param string $package        Full path to the package file.
       	 * @param bool   $delete_package Optional. Whether to delete the package file after attempting
       	 *                               to unpack it. Default true.
       	 * @return string|WP_Error The path to the unpacked contents, or a {@see WP_Error} on failure.
       	 */
       	public function unpack_package( $package, $delete_package = true ) {
       		global $wp_filesystem;
   
       		$this->skin->feedback('unpack_package');
   
       		$upgrade_folder = $wp_filesystem->wp_content_dir() . 'upgrade/';
   
       		//Clean up contents of upgrade directory beforehand.
       		$upgrade_files = $wp_filesystem->dirlist($upgrade_folder);
       		if ( !empty($upgrade_files) ) {
       			foreach ( $upgrade_files as $file )
       				$wp_filesystem->delete($upgrade_folder . $file['name'], true);
       		}
   
       		// We need a working directory - Strip off any .tmp or .zip suffixes
       		$working_dir = $upgrade_folder . basename( basename( $package, '.tmp' ), '.zip' );
   
       		// Clean up working directory
       		if ( $wp_filesystem->is_dir($working_dir) )
       			$wp_filesystem->delete($working_dir, true);
   
       		// Unzip package to working directory
       		$result = unzip_file( $package, $working_dir );
   
       		// Once extracted, delete the package if required.
       		if ( $delete_package )
       			unlink($package);
   
       		if ( is_wp_error($result) ) {
       			$wp_filesystem->delete($working_dir, true);
       			if ( 'incompatible_archive' == $result->get_error_code() ) {
       				return new WP_Error( 'incompatible_archive', $this->strings['incompatible_archive'], $result->get_error_data() );
       			}
       			return $result;
       		}
   
       		return $working_dir;
       	}
   
       	/**
       	 * Clears the directory where this item is going to be installed into.
       	 *
       	 * @since 4.3.0
       	 * @access public
       	 *
       	 * @global WP_Filesystem_Base $wp_filesystem Subclass
       	 *
       	 * @param string $remote_destination The location on the remote filesystem to be cleared
       	 * @return bool|WP_Error True upon success, WP_Error on failure.
       	 */
       	public function clear_destination( $remote_destination ) {
       		global $wp_filesystem;
   
       		if ( ! $wp_filesystem->exists( $remote_destination ) ) {
       			return true;
       		}
   
       		// Check all files are writable before attempting to clear the destination.
       		$unwritable_files = array();
   
       		$_files = $wp_filesystem->dirlist( $remote_destination, true, true );
   
       		// Flatten the resulting array, iterate using each as we append to the array during iteration.
       		while ( $f = each( $_files ) ) {
       			$file = $f['value'];
       			$name = $f['key'];
   
       			if ( ! isset( $file['files'] ) ) {
       				continue;
       			}
   
       			foreach ( $file['files'] as $filename => $details ) {
       				$_files[ $name . '/' . $filename ] = $details;
       			}
       		}
   
       		// Check writability.
       		foreach ( $_files as $filename => $file_details ) {
       			if ( ! $wp_filesystem->is_writable( $remote_destination . $filename ) ) {
   
       				// Attempt to alter permissions to allow writes and try again.
       				$wp_filesystem->chmod( $remote_destination . $filename, ( 'd' == $file_details['type'] ? FS_CHMOD_DIR : FS_CHMOD_FILE ) );
       				if ( ! $wp_filesystem->is_writable( $remote_destination . $filename ) ) {
       					$unwritable_files[] = $filename;
       				}
       			}
       		}
   
       		if ( ! empty( $unwritable_files ) ) {
       			return new WP_Error( 'files_not_writable', $this->strings['files_not_writable'], implode( ', ', $unwritable_files ) );
       		}
   
       		if ( ! $wp_filesystem->delete( $remote_destination, true ) ) {
       			return new WP_Error( 'remove_old_failed', $this->strings['remove_old_failed'] );
       		}
   
       		return true;
       	}
   
       	/**
       	 * Install a package.
       	 *
       	 * Copies the contents of a package form a source directory, and installs them in
       	 * a destination directory. Optionally removes the source. It can also optionally
       	 * clear out the destination folder if it already exists.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @global WP_Filesystem_Base $wp_filesystem Subclass
       	 * @global array              $wp_theme_directories
       	 *
       	 * @param array|string $args {
       	 *     Optional. Array or string of arguments for installing a package. Default empty array.
       	 *
       	 *     @type string $source                      Required path to the package source. Default empty.
       	 *     @type string $destination                 Required path to a folder to install the package in.
       	 *                                               Default empty.
       	 *     @type bool   $clear_destination           Whether to delete any files already in the destination
       	 *                                               folder. Default false.
       	 *     @type bool   $clear_working               Whether to delete the files form the working directory
       	 *                                               after copying to the destination. Default false.
       	 *     @type bool   $abort_if_destination_exists Whether to abort the installation if
       	 *                                               the destination folder already exists. Default true.
       	 *     @type array  $hook_extra                  Extra arguments to pass to the filter hooks called by
       	 *                                               {@see WP_Upgrader::install_package()}. Default empty array.
       	 * }
       	 *
       	 * @return array|WP_Error The result (also stored in <code>WP_Upgrader:$result</code>), or a {@see WP_Error} on failure.
       	 */
       	public function install_package( $args = array() ) {
       		global $wp_filesystem, $wp_theme_directories;
   
       		$defaults = array(
       			'source' => '', // Please always pass this
       			'destination' => '', // and this
       			'clear_destination' => false,
       			'clear_working' => false,
       			'abort_if_destination_exists' => true,
       			'hook_extra' => array()
       		);
   
       		$args = wp_parse_args($args, $defaults);
   
       		// These were previously extract()'d.
       		$source = $args['source'];
       		$destination = $args['destination'];
       		$clear_destination = $args['clear_destination'];
   
       		@set_time_limit( 300 );
   
       		if ( empty( $source ) || empty( $destination ) ) {
       			return new WP_Error( 'bad_request', $this->strings['bad_request'] );
       		}
       		$this->skin->feedback( 'installing_package' );
   
       		/**
       		 * Filter the install response before the installation has started.
       		 *
       		 * Returning a truthy value, or one that could be evaluated as a WP_Error
       		 * will effectively short-circuit the installation, returning that value
       		 * instead.
       		 *
       		 * @since 2.8.0
       		 *
       		 * @param bool|WP_Error $response   Response.
       		 * @param array         $hook_extra Extra arguments passed to hooked filters.
       		 */
       		$res = apply_filters( 'upgrader_pre_install', true, $args['hook_extra'] );
   
       		if ( is_wp_error( $res ) ) {
       			return $res;
       		}
   
       		//Retain the Original source and destinations
       		$remote_source = $args['source'];
       		$local_destination = $destination;
   
       		$source_files = array_keys( $wp_filesystem->dirlist( $remote_source ) );
       		$remote_destination = $wp_filesystem->find_folder( $local_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.
       			$source = trailingslashit( $args['source'] ) . trailingslashit( $source_files[0] );
       		} elseif ( count( $source_files ) == 0 ) {
       			return new WP_Error( 'incompatible_archive_empty', $this->strings['incompatible_archive'], $this->strings['no_files'] ); // There are no files?
       		} 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.
       			$source = trailingslashit( $args['source'] );
       		}
   
       		/**
       		 * Filter the source file location for the upgrade package.
       		 *
       		 * @since 2.8.0
       		 * @since 4.4.0 The $hook_extra parameter became available.
       		 *
       		 * @param string      $source        File source location.
       		 * @param string      $remote_source Remote file source location.
       		 * @param WP_Upgrader $this          WP_Upgrader instance.
       		 * @param array       $hook_extra    Extra arguments passed to hooked filters.
       		 */
       		$source = apply_filters( 'upgrader_source_selection', $source, $remote_source, $this, $args['hook_extra'] );
   
       		if ( is_wp_error( $source ) ) {
       			return $source;
       		}
   
       		// Has the source location changed? If so, we need a new source_files list.
       		if ( $source !== $remote_source ) {
       			$source_files = array_keys( $wp_filesystem->dirlist( $source ) );
       		}
   
       		/*
       		 * Protection against deleting files in any important base directories.
       		 * Theme_Upgrader & Plugin_Upgrader also trigger this, as they pass the
       		 * destination directory (WP_PLUGIN_DIR / wp-content/themes) intending
       		 * to copy the directory into the directory, whilst they pass the source
       		 * as the actual files to copy.
       		 */
       		$protected_directories = array( ABSPATH, WP_CONTENT_DIR, WP_PLUGIN_DIR, WP_CONTENT_DIR . '/themes' );
   
       		if ( is_array( $wp_theme_directories ) ) {
       			$protected_directories = array_merge( $protected_directories, $wp_theme_directories );
       		}
   
       		if ( in_array( $destination, $protected_directories ) ) {
       			$remote_destination = trailingslashit( $remote_destination ) . trailingslashit( basename( $source ) );
       			$destination = trailingslashit( $destination ) . trailingslashit( basename( $source ) );
       		}
   
       		if ( $clear_destination ) {
       			// We're going to clear the destination if there's something there.
       			$this->skin->feedback('remove_old');
   
       			$removed = $this->clear_destination( $remote_destination );
   
       			/**
       			 * Filter whether the upgrader cleared the destination.
       			 *
       			 * @since 2.8.0
       			 *
       			 * @param mixed  $removed            Whether the destination was cleared. true on success, WP_Error on failure
       			 * @param string $local_destination  The local package destination.
       			 * @param string $remote_destination The remote package destination.
       			 * @param array  $hook_extra         Extra arguments passed to hooked filters.
       			 */
       			$removed = apply_filters( 'upgrader_clear_destination', $removed, $local_destination, $remote_destination, $args['hook_extra'] );
   
       			if ( is_wp_error( $removed ) ) {
       				return $removed;
       			}
       		} elseif ( $args['abort_if_destination_exists'] && $wp_filesystem->exists($remote_destination) ) {
       			//If we're not clearing the destination folder and something exists there already, Bail.
       			//But first check to see if there are actually any files in the folder.
       			$_files = $wp_filesystem->dirlist($remote_destination);
       			if ( ! empty($_files) ) {
       				$wp_filesystem->delete($remote_source, true); //Clear out the source files.
       				return new WP_Error('folder_exists', $this->strings['folder_exists'], $remote_destination );
       			}
       		}
   
       		//Create destination if needed
       		if ( ! $wp_filesystem->exists( $remote_destination ) ) {
       			if ( ! $wp_filesystem->mkdir( $remote_destination, FS_CHMOD_DIR ) ) {
       				return new WP_Error( 'mkdir_failed_destination', $this->strings['mkdir_failed'], $remote_destination );
       			}
       		}
       		// Copy new version of item into place.
       		$result = copy_dir($source, $remote_destination);
       		if ( is_wp_error($result) ) {
       			if ( $args['clear_working'] ) {
       				$wp_filesystem->delete( $remote_source, true );
       			}
       			return $result;
       		}
   
       		//Clear the Working folder?
       		if ( $args['clear_working'] ) {
       			$wp_filesystem->delete( $remote_source, true );
       		}
   
       		$destination_name = basename( str_replace($local_destination, '', $destination) );
       		if ( '.' == $destination_name ) {
       			$destination_name = '';
       		}
   
       		$this->result = compact( 'source', 'source_files', 'destination', 'destination_name', 'local_destination', 'remote_destination', 'clear_destination' );
   
       		/**
       		 * Filter the install response after the installation has finished.
       		 *
       		 * @since 2.8.0
       		 *
       		 * @param bool  $response   Install response.
       		 * @param array $hook_extra Extra arguments passed to hooked filters.
       		 * @param array $result     Installation result data.
       		 */
       		$res = apply_filters( 'upgrader_post_install', true, $args['hook_extra'], $this->result );
   
       		if ( is_wp_error($res) ) {
       			$this->result = $res;
       			return $res;
       		}
   
       		//Bombard the calling function will all the info which we've just used.
       		return $this->result;
       	}
   
       	/**
       	 * Run an upgrade/install.
       	 *
       	 * Attempts to download the package (if it is not a local file), unpack it, and
       	 * install it in the destination folder.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @param array $options {
       	 *     Array or string of arguments for upgrading/installing a package.
       	 *
       	 *     @type string $package                     The full path or URI of the package to install.
       	 *                                               Default empty.
       	 *     @type string $destination                 The full path to the destination folder.
       	 *                                               Default empty.
       	 *     @type bool   $clear_destination           Whether to delete any files already in the
       	 *                                               destination folder. Default false.
       	 *     @type bool   $clear_working               Whether to delete the files form the working
       	 *                                               directory after copying to the destination.
       	 *                                               Default false.
       	 *     @type bool   $abort_if_destination_exists Whether to abort the installation if the destination
       	 *                                               folder already exists. When true, <code>$clear_destination</code>
       	 *                                               should be false. Default true.
       	 *     @type bool   $is_multi                    Whether this run is one of multiple upgrade/install
       	 *                                               actions being performed in bulk. When true, the skin
       	 *                                               {@see WP_Upgrader::header()} and {@see WP_Upgrader::footer()}
       	 *                                               aren't called. Default false.
       	 *     @type array  $hook_extra                  Extra arguments to pass to the filter hooks called by
       	 *                                               {@see WP_Upgrader::run()}.
       	 * }
       	 * @return array|false|WP_error The result from self::install_package() on success, otherwise a WP_Error,
       	 *                              or false if unable to connect to the filesystem.
       	 */
       	public function run( $options ) {
   
       		$defaults = array(
       			'package' => '', // Please always pass this.
       			'destination' => '', // And this
       			'clear_destination' => false,
       			'abort_if_destination_exists' => true, // Abort if the Destination directory exists, Pass clear_destination as false please
       			'clear_working' => true,
       			'is_multi' => false,
       			'hook_extra' => array() // Pass any extra $hook_extra args here, this will be passed to any hooked filters.
       		);
   
       		$options = wp_parse_args( $options, $defaults );
   
       		/**
       		 * Filter the package options before running an update.
       		 *
       		 * @since 4.3.0
       		 *
       		 * @param array $options {
       		 *     Options used by the upgrader.
       		 *
       		 *     @type string $package                     Package for update.
       		 *     @type string $destination                 Update location.
       		 *     @type bool   $clear_destination           Clear the destination resource.
       		 *     @type bool   $clear_working               Clear the working resource.
       		 *     @type bool   $abort_if_destination_exists Abort if the Destination directory exists.
       		 *     @type bool   $is_multi                    Whether the upgrader is running multiple times.
       		 *     @type array  $hook_extra                  Extra hook arguments.
       		 * }
       		 */
       		$options = apply_filters( 'upgrader_package_options', $options );
   
       		if ( ! $options['is_multi'] ) { // call $this->header separately if running multiple times
       			$this->skin->header();
       		}
   
       		// Connect to the Filesystem first.
       		$res = $this->fs_connect( array( WP_CONTENT_DIR, $options['destination'] ) );
       		// Mainly for non-connected filesystem.
       		if ( ! $res ) {
       			if ( ! $options['is_multi'] ) {
       				$this->skin->footer();
       			}
       			return false;
       		}
   
       		$this->skin->before();
   
       		if ( is_wp_error($res) ) {
       			$this->skin->error($res);
       			$this->skin->after();
       			if ( ! $options['is_multi'] ) {
       				$this->skin->footer();
       			}
       			return $res;
       		}
   
       		/*
       		 * Download the package (Note, This just returns the filename
       		 * of the file if the package is a local file)
       		 */
       		$download = $this->download_package( $options['package'] );
       		if ( is_wp_error($download) ) {
       			$this->skin->error($download);
       			$this->skin->after();
       			if ( ! $options['is_multi'] ) {
       				$this->skin->footer();
       			}
       			return $download;
       		}
   
       		$delete_package = ( $download != $options['package'] ); // Do not delete a "local" file
   
       		// Unzips the file into a temporary directory.
       		$working_dir = $this->unpack_package( $download, $delete_package );
       		if ( is_wp_error($working_dir) ) {
       			$this->skin->error($working_dir);
       			$this->skin->after();
       			if ( ! $options['is_multi'] ) {
       				$this->skin->footer();
       			}
       			return $working_dir;
       		}
   
       		// With the given options, this installs it to the destination directory.
       		$result = $this->install_package( array(
       			'source' => $working_dir,
       			'destination' => $options['destination'],
       			'clear_destination' => $options['clear_destination'],
       			'abort_if_destination_exists' => $options['abort_if_destination_exists'],
       			'clear_working' => $options['clear_working'],
       			'hook_extra' => $options['hook_extra']
       		) );
   
       		$this->skin->set_result($result);
       		if ( is_wp_error($result) ) {
       			$this->skin->error($result);
       			$this->skin->feedback('process_failed');
       		} else {
       			// Install succeeded.
       			$this->skin->feedback('process_success');
       		}
   
       		$this->skin->after();
   
       		if ( ! $options['is_multi'] ) {
   
       			/** This action is documented in wp-admin/includes/class-wp-upgrader.php */
       			do_action( 'upgrader_process_complete', $this, $options['hook_extra'] );
       			$this->skin->footer();
       		}
   
       		return $result;
       	}
   
       	/**
       	 * Toggle maintenance mode for the site.
       	 *
       	 * Creates/deletes the maintenance file to enable/disable maintenance mode.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @global WP_Filesystem_Base $wp_filesystem Subclass
       	 *
       	 * @param bool $enable True to enable maintenance mode, false to disable.
       	 */
       	public function maintenance_mode( $enable = false ) {
       		global $wp_filesystem;
       		$file = $wp_filesystem->abspath() . '.maintenance';
       		if ( $enable ) {
       			$this->skin->feedback('maintenance_start');
       			// Create maintenance file to signal that we are upgrading
       			$maintenance_string = '<?php $upgrading = ' . time() . '; ?>';
       			$wp_filesystem->delete($file);
       			$wp_filesystem->put_contents($file, $maintenance_string, FS_CHMOD_FILE);
       		} elseif ( ! $enable && $wp_filesystem->exists( $file ) ) {
       			$this->skin->feedback('maintenance_end');
       			$wp_filesystem->delete($file);
       		}
       	}
   
       	/**
        	 * Creates a lock using WordPress options.
        	 *
        	 * @since 4.5.0
        	 * @access public
        	 * @static
        	 *
        	 * @param string $lock_name       The name of this unique lock.
        	 * @param int    $release_timeout Optional. The duration in seconds to respect an existing lock.
       	 *                                Default: 1 hour.
        	 * @return bool False if a lock couldn't be created or if the lock is no longer valid. True otherwise.
        	 */
       	public static function create_lock( $lock_name, $release_timeout = null ) {
       		global $wpdb;
       		if ( ! $release_timeout ) {
       			$release_timeout = HOUR_IN_SECONDS;
       		}
       		$lock_option = $lock_name . '.lock';
   
       		// Try to lock.
       		$lock_result = $wpdb->query( $wpdb->prepare( "INSERT IGNORE INTO <code>$wpdb->options</code> ( <code>option_name</code>, <code>option_value</code>, <code>autoload</code> ) VALUES (%s, %s, 'no') /* LOCK */", $lock_option, time() ) );
   
       		if ( ! $lock_result ) {
       			$lock_result = get_option( $lock_option );
   
       			// If a lock couldn't be created, and there isn't a lock, bail.
       			if ( ! $lock_result ) {
       				return false;
       			}
   
       			// Check to see if the lock is still valid. If not, bail.
       			if ( $lock_result > ( time() - $release_timeout ) ) {
       				return false;
       			}
   
       			// There must exist an expired lock, clear it and re-gain it.
       			WP_Upgrader::release_lock( $lock_name );
   
       			return WP_Upgrader::create_lock( $lock_name, $release_timeout );
       		}
   
       		// Update the lock, as by this point we've definitely got a lock, just need to fire the actions.
       		update_option( $lock_option, time() );
   
       		return true;
       	}
   
       	/**
        	 * Releases an upgrader lock.
        	 *
        	 * @since 4.5.0
        	 * @access public
        	 * @static
       	 *
       	 * @see WP_Upgrader::create_lock()
        	 *
        	 * @param string $lock_name The name of this unique lock.
       	 * @return bool True if the lock was successfully released. False on failure.
        	 */
       	public static function release_lock( $lock_name ) {
       		return delete_option( $lock_name . '.lock' );
       	}
   
       }
   
       /**
        * Core class used for upgrading/installing plugins.
        *
        * It is designed to upgrade/install plugins from a local zip, remote zip URL,
        * or uploaded zip file.
        *
        * @since 2.8.0
        *
        * @see WP_Upgrader
        */
       class Plugin_Upgrader extends WP_Upgrader {
   
       	/**
       	 * Plugin upgrade result.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 * @var array|WP_Error $result
       	 *
       	 * @see WP_Upgrader::$result
       	 */
       	public $result;
   
       	/**
       	 * Whether a bulk upgrade/install is being performed.
       	 *
       	 * @since 2.9.0
       	 * @access public
       	 * @var bool $bulk
       	 */
       	public $bulk = false;
   
       	/**
       	 * Initialize the upgrade strings.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 */
       	public function upgrade_strings() {
       		$this->strings['up_to_date'] = __('The plugin is at the latest version.');
       		$this->strings['no_package'] = __('Update package not available.');
       		$this->strings['downloading_package'] = __('Downloading update from <span class="code">%s</span>…');
       		$this->strings['unpack_package'] = __('Unpacking the update…');
       		$this->strings['remove_old'] = __('Removing the old version of the plugin…');
       		$this->strings['remove_old_failed'] = __('Could not remove the old plugin.');
       		$this->strings['process_failed'] = __('Plugin update failed.');
       		$this->strings['process_success'] = __('Plugin updated successfully.');
       		$this->strings['process_bulk_success'] = __('Plugins updated successfully.');
       	}
   
       	/**
       	 * Initialize the install strings.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 */
       	public function install_strings() {
       		$this->strings['no_package'] = __('Install package not available.');
       		$this->strings['downloading_package'] = __('Downloading install package from <span class="code">%s</span>…');
       		$this->strings['unpack_package'] = __('Unpacking the package…');
       		$this->strings['installing_package'] = __('Installing the plugin…');
       		$this->strings['no_files'] = __('The plugin contains no files.');
       		$this->strings['process_failed'] = __('Plugin install failed.');
       		$this->strings['process_success'] = __('Plugin installed successfully.');
       	}
   
       	/**
       	 * Install a plugin package.
       	 *
       	 * @since 2.8.0
       	 * @since 3.7.0 The <code>$args</code> parameter was added, making clearing the plugin update cache optional.
       	 * @access public
       	 *
       	 * @param string $package The full local path or URI of the package.
       	 * @param array  $args {
       	 *     Optional. Other arguments for installing a plugin package. Default empty array.
       	 *
       	 *     @type bool $clear_update_cache Whether to clear the plugin updates cache if successful.
       	 *                                    Default true.
       	 * }
       	 * @return bool|WP_Error True if the install was successful, false or a WP_Error otherwise.
       	 */
       	public function install( $package, $args = array() ) {
   
       		$defaults = array(
       			'clear_update_cache' => true,
       		);
       		$parsed_args = wp_parse_args( $args, $defaults );
   
       		$this->init();
       		$this->install_strings();
   
       		add_filter('upgrader_source_selection', array($this, 'check_package') );
       		// Clear cache so wp_update_plugins() knows about the new plugin.
       		add_action( 'upgrader_process_complete', 'wp_clean_plugins_cache', 9, 0 );
   
       		$this->run( array(
       			'package' => $package,
       			'destination' => WP_PLUGIN_DIR,
       			'clear_destination' => false, // Do not overwrite files.
       			'clear_working' => true,
       			'hook_extra' => array(
       				'type' => 'plugin',
       				'action' => 'install',
       			)
       		) );
   
       		remove_action( 'upgrader_process_complete', 'wp_clean_plugins_cache', 9 );
       		remove_filter('upgrader_source_selection', array($this, 'check_package') );
   
       		if ( ! $this->result || is_wp_error($this->result) )
       			return $this->result;
   
       		// Force refresh of plugin update information
       		wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
   
       		return true;
       	}
   
       	/**
       	 * Upgrade a plugin.
       	 *
       	 * @since 2.8.0
       	 * @since 3.7.0 The <code>$args</code> parameter was added, making clearing the plugin update cache optional.
       	 * @access public
       	 *
       	 * @param string $plugin The basename path to the main plugin file.
       	 * @param array  $args {
       	 *     Optional. Other arguments for upgrading a plugin package. Default empty array.
       	 *
       	 *     @type bool $clear_update_cache Whether to clear the plugin updates cache if successful.
       	 *                                    Default true.
       	 * }
       	 * @return bool|WP_Error True if the upgrade was successful, false or a {@see WP_Error} object otherwise.
       	 */
       	public function upgrade( $plugin, $args = array() ) {
   
       		$defaults = array(
       			'clear_update_cache' => true,
       		);
       		$parsed_args = wp_parse_args( $args, $defaults );
   
       		$this->init();
       		$this->upgrade_strings();
   
       		$current = get_site_transient( 'update_plugins' );
       		if ( !isset( $current->response[ $plugin ] ) ) {
       			$this->skin->before();
       			$this->skin->set_result(false);
       			$this->skin->error('up_to_date');
       			$this->skin->after();
       			return false;
       		}
   
       		// Get the URL to the zip file
       		$r = $current->response[ $plugin ];
   
       		add_filter('upgrader_pre_install', array($this, 'deactivate_plugin_before_upgrade'), 10, 2);
       		add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4);
       		//'source_selection' => array($this, 'source_selection'), //there's a trac ticket to move up the directory for zip's which are made a bit differently, useful for non-.org plugins.
   
       		$this->run( array(
       			'package' => $r->package,
       			'destination' => WP_PLUGIN_DIR,
       			'clear_destination' => true,
       			'clear_working' => true,
       			'hook_extra' => array(
       				'plugin' => $plugin,
       				'type' => 'plugin',
       				'action' => 'update',
       			),
       		) );
   
       		// Cleanup our hooks, in case something else does a upgrade on this connection.
       		remove_filter('upgrader_pre_install', array($this, 'deactivate_plugin_before_upgrade'));
       		remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'));
   
       		if ( ! $this->result || is_wp_error($this->result) )
       			return $this->result;
   
       		// Force refresh of plugin update information
       		wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
   
       		return true;
       	}
   
       	/**
       	 * Bulk upgrade several plugins at once.
       	 *
       	 * @since 2.8.0
       	 * @since 3.7.0 The <code>$args</code> parameter was added, making clearing the plugin update cache optional.
       	 * @access public
       	 *
       	 * @param array $plugins Array of the basename paths of the plugins' main files.
       	 * @param array $args {
       	 *     Optional. Other arguments for upgrading several plugins at once. Default empty array.
       	 *
       	 *     @type bool $clear_update_cache Whether to clear the plugin updates cache if successful.
       	 *                                    Default true.
       	 * }
       	 * @return array|false An array of results indexed by plugin file, or false if unable to connect to the filesystem.
       	 */
       	public function bulk_upgrade( $plugins, $args = array() ) {
   
       		$defaults = array(
       			'clear_update_cache' => true,
       		);
       		$parsed_args = wp_parse_args( $args, $defaults );
   
       		$this->init();
       		$this->bulk = true;
       		$this->upgrade_strings();
   
       		$current = get_site_transient( 'update_plugins' );
   
       		add_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'), 10, 4);
   
       		$this->skin->header();
   
       		// Connect to the Filesystem first.
       		$res = $this->fs_connect( array(WP_CONTENT_DIR, WP_PLUGIN_DIR) );
       		if ( ! $res ) {
       			$this->skin->footer();
       			return false;
       		}
   
       		$this->skin->bulk_header();
   
       		/*
       		 * Only start maintenance mode if:
       		 * - running Multisite and there are one or more plugins specified, OR
       		 * - a plugin with an update available is currently active.
       		 * @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible.
       		 */
       		$maintenance = ( is_multisite() && ! empty( $plugins ) );
       		foreach ( $plugins as $plugin )
       			$maintenance = $maintenance || ( is_plugin_active( $plugin ) && isset( $current->response[ $plugin] ) );
       		if ( $maintenance )
       			$this->maintenance_mode(true);
   
       		$results = array();
   
       		$this->update_count = count($plugins);
       		$this->update_current = 0;
       		foreach ( $plugins as $plugin ) {
       			$this->update_current++;
       			$this->skin->plugin_info = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin, false, true);
   
       			if ( !isset( $current->response[ $plugin ] ) ) {
       				$this->skin->set_result('up_to_date');
       				$this->skin->before();
       				$this->skin->feedback('up_to_date');
       				$this->skin->after();
       				$results[$plugin] = true;
       				continue;
       			}
   
       			// Get the URL to the zip file.
       			$r = $current->response[ $plugin ];
   
       			$this->skin->plugin_active = is_plugin_active($plugin);
   
       			$result = $this->run( array(
       				'package' => $r->package,
       				'destination' => WP_PLUGIN_DIR,
       				'clear_destination' => true,
       				'clear_working' => true,
       				'is_multi' => true,
       				'hook_extra' => array(
       					'plugin' => $plugin
       				)
       			) );
   
       			$results[$plugin] = $this->result;
   
       			// Prevent credentials auth screen from displaying multiple times
       			if ( false === $result )
       				break;
       		} //end foreach $plugins
   
       		$this->maintenance_mode(false);
   
       		/**
       		 * Fires when the bulk upgrader process is complete.
       		 *
       		 * @since 3.6.0
       		 *
       		 * @param Plugin_Upgrader $this Plugin_Upgrader instance. In other contexts, $this, might
       		 *                              be a Theme_Upgrader or Core_Upgrade instance.
       		 * @param array           $data {
       		 *     Array of bulk item update data.
       		 *
       		 *     @type string $action   Type of action. Default 'update'.
       		 *     @type string $type     Type of update process. Accepts 'plugin', 'theme', or 'core'.
       		 *     @type bool   $bulk     Whether the update process is a bulk update. Default true.
       		 *     @type array  $packages Array of plugin, theme, or core packages to update.
       		 * }
       		 */
       		do_action( 'upgrader_process_complete', $this, array(
       			'action' => 'update',
       			'type' => 'plugin',
       			'bulk' => true,
       			'plugins' => $plugins,
       		) );
   
       		$this->skin->bulk_footer();
   
       		$this->skin->footer();
   
       		// Cleanup our hooks, in case something else does a upgrade on this connection.
       		remove_filter('upgrader_clear_destination', array($this, 'delete_old_plugin'));
   
       		// Force refresh of plugin update information.
       		wp_clean_plugins_cache( $parsed_args['clear_update_cache'] );
   
       		return $results;
       	}
   
       	/**
       	 * Check a source package to be sure it contains a plugin.
       	 *
       	 * This function is added to the {@see 'upgrader_source_selection'} filter by
       	 * {@see Plugin_Upgrader::install()}.
       	 *
       	 * @since 3.3.0
       	 * @access public
       	 *
       	 * @global WP_Filesystem_Base $wp_filesystem Subclass
       	 *
       	 * @param string $source The path to the downloaded package source.
       	 * @return string|WP_Error The source as passed, or a {@see WP_Error} object
       	 *                         if no plugins were found.
       	 */
       	public function check_package($source) {
       		global $wp_filesystem;
   
       		if ( is_wp_error($source) )
       			return $source;
   
       		$working_directory = str_replace( $wp_filesystem->wp_content_dir(), trailingslashit(WP_CONTENT_DIR), $source);
       		if ( ! is_dir($working_directory) ) // Sanity check, if the above fails, let's not prevent installation.
       			return $source;
   
       		// Check the folder contains at least 1 valid plugin.
       		$plugins_found = false;
       		$files = glob( $working_directory . '*.php' );
       		if ( $files ) {
       			foreach ( $files as $file ) {
       				$info = get_plugin_data( $file, false, false );
       				if ( ! empty( $info['Name'] ) ) {
       					$plugins_found = true;
       					break;
       				}
       			}
       		}
   
       		if ( ! $plugins_found )
       			return new WP_Error( 'incompatible_archive_no_plugins', $this->strings['incompatible_archive'], __( 'No valid plugins were found.' ) );
   
       		return $source;
       	}
   
       	/**
       	 * Retrieve the path to the file that contains the plugin info.
       	 *
       	 * This isn't used internally in the class, but is called by the skins.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @return string|false The full path to the main plugin file, or false.
       	 */
       	public function plugin_info() {
       		if ( ! is_array($this->result) )
       			return false;
       		if ( empty($this->result['destination_name']) )
       			return false;
   
       		$plugin = get_plugins('/' . $this->result['destination_name']); //Ensure to pass with leading slash
       		if ( empty($plugin) )
       			return false;
   
       		$pluginfiles = array_keys($plugin); //Assume the requested plugin is the first in the list
   
       		return $this->result['destination_name'] . '/' . $pluginfiles[0];
       	}
   
       	/**
       	 * Deactivates a plugin before it is upgraded.
       	 *
       	 * Hooked to the {@see 'upgrader_pre_install'} filter by {@see Plugin_Upgrader::upgrade()}.
       	 *
       	 * @since 2.8.0
       	 * @since 4.1.0 Added a return value.
       	 * @access public
       	 *
       	 * @param bool|WP_Error  $return Upgrade offer return.
       	 * @param array          $plugin Plugin package arguments.
       	 * @return bool|WP_Error The passed in $return param or {@see WP_Error}.
       	 */
       	public function deactivate_plugin_before_upgrade($return, $plugin) {
   
       		if ( is_wp_error($return) ) //Bypass.
       			return $return;
   
       		// When in cron (background updates) don't deactivate the plugin, as we require a browser to reactivate it
       		if ( defined( 'DOING_CRON' ) && DOING_CRON )
       			return $return;
   
       		$plugin = isset($plugin['plugin']) ? $plugin['plugin'] : '';
       		if ( empty($plugin) )
       			return new WP_Error('bad_request', $this->strings['bad_request']);
   
       		if ( is_plugin_active($plugin) ) {
       			//Deactivate the plugin silently, Prevent deactivation hooks from running.
       			deactivate_plugins($plugin, true);
       		}
   
       		return $return;
       	}
   
       	/**
       	 * Delete the old plugin during an upgrade.
       	 *
       	 * Hooked to the {@see 'upgrader_clear_destination'} filter by
       	 * {@see Plugin_Upgrader::upgrade()} and {@see Plugin_Upgrader::bulk_upgrade()}.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 *
       	 * @global WP_Filesystem_Base $wp_filesystem Subclass
            *
       	 * @param bool|WP_Error $removed
       	 * @param string        $local_destination
       	 * @param string        $remote_destination
       	 * @param array         $plugin
       	 * @return WP_Error|bool
       	 */
       	public function delete_old_plugin($removed, $local_destination, $remote_destination, $plugin) {
       		global $wp_filesystem;
   
       		if ( is_wp_error($removed) )
       			return $removed; //Pass errors through.
   
       		$plugin = isset($plugin['plugin']) ? $plugin['plugin'] : '';
       		if ( empty($plugin) )
       			return new WP_Error('bad_request', $this->strings['bad_request']);
   
       		$plugins_dir = $wp_filesystem->wp_plugins_dir();
       		$this_plugin_dir = trailingslashit( dirname($plugins_dir . $plugin) );
   
       		if ( ! $wp_filesystem->exists($this_plugin_dir) ) //If it's already vanished.
       			return $removed;
   
       		// If plugin is in its own directory, recursively delete the directory.
       		if ( strpos($plugin, '/') && $this_plugin_dir != $plugins_dir ) //base check on if plugin includes directory separator AND that it's not the root plugin folder
       			$deleted = $wp_filesystem->delete($this_plugin_dir, true);
       		else
       			$deleted = $wp_filesystem->delete($plugins_dir . $plugin);
   
       		if ( ! $deleted )
       			return new WP_Error('remove_old_failed', $this->strings['remove_old_failed']);
   
       		return true;
       	}
       }
   
       /**
        * Core class used for upgrading/installing themes.
        *
        * It is designed to upgrade/install themes from a local zip, remote zip URL,
        * or uploaded zip file.
        *
        * @since 2.8.0
        *
        * @see WP_Upgrader
        */
       class Theme_Upgrader extends WP_Upgrader {
   
       	/**
       	 * Result of the theme upgrade offer.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 * @var array|WP_Error $result
       	 * @see WP_Upgrader::$result
       	 */
       	public $result;
   
       	/**
       	 * Whether multiple themes are being upgraded/installed in bulk.
       	 *
       	 * @since 2.9.0
       	 * @access public
       	 * @var bool $bulk
       	 */
       	public $bulk = false;
   
       	/**
       	 * Initialize the upgrade strings.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 */
       	public function upgrade_strings() {
       		$this->strings['up_to_date'] = __('The theme is at the latest version.');
       		$this->strings['no_package'] = __('Update package not available.');
       		$this->strings['downloading_package'] = __('Downloading update from <span class="code">%s</span>…');
       		$this->strings['unpack_package'] = __('Unpacking the update…');
       		$this->strings['remove_old'] = __('Removing the old version of the theme…');
       		$this->strings['remove_old_failed'] = __('Could not remove the old theme.');
       		$this->strings['process_failed'] = __('Theme update failed.');
       		$this->strings['process_success'] = __('Theme updated successfully.');
       	}
   
       	/**
       	 * Initialize the install strings.
       	 *
       	 * @since 2.8.0
       	 * @access public
       	 */
       	public function install_strings() {
       		$this->strings['no_package'] = __('Install package not available.');
       		$this->strings['downloading_package'] = __('Downloading install package from <span class="code">%s</span>…');
       		$this->strings['unpack_package'] = __('Unpacking the package…');
       		$this->strings['installing_package'] = __('Installing the theme…');
       		$this->strings['no_files'] = __('The theme contains no files.');
       		$this->strings['process_failed'] = __('Theme install failed.');
       		$this->strings['process_success'] = __('Theme installed successfully.');
       		/* translators: 1: theme name, 2: version */
       		$this->strings['process_success_specific'] = __('Successfully installed the theme <strong>%1$s %2$s</strong>.');
       		$this->strings['parent_theme_search'] = __('This theme requires a parent theme. Checking if it is installed…');
       		/* translators: 1: theme name, 2: version */
       		$this->strings['parent_theme_prepare_install'] = __('Preparing to install <strong>%1$s %2$s</strong>…');
       		/* translators: 1: theme name, 2: version */
       		$this->strings['parent_theme_currently_installed'] = __('The parent theme, <strong>%1$s %2$s</strong>, is currently installed.');
       		/* translators: 1: theme name, 2: version */
       		$this->strings['parent_theme_install_success'] = __('Successfully installed the parent theme, <strong>%1$s %2$s</strong>.');
       		$this->strings['parent_theme_not_found'] = __('<strong>The parent theme could not be found.</strong> You will need to install the parent theme, <strong>%s</strong>, before you can use this child theme.');
       	}
   
       	/**
       	 * Check if a child theme is being installed and we need to install its parent.
       	 *
       	 * Hooked to the {@see 'upgrader_post_install'} filter by {@see Theme_Upgrader::install()}.
       	 *
       	 * @since 3.4.0
       	 * @access public
       	 *
       	 * @param bool  $install_result
       	 * @param array $hook_extra
       	 * @param array $child_result
       	 * @return type
       	 */
       	public function check_parent_theme_filter( $install_result, $hook_extra, $child_result ) {
       		// Check to see if we need to install a parent theme
       		$theme_info = $this->theme_info();
   
       		if ( ! $theme_info->parent() )
       			return $install_result;
   
       		$this->skin->feedback( 'parent_theme_search' );
   
       		if ( ! $theme_info->parent()->errors() ) {
       			$this->skin->feedback( 'parent_theme_currently_installed', $theme_info->parent()->display('Name'), $theme_info->parent()->display('Version') );
       			// We already have the theme, fall through.
       			return $install_result;
       		}
   
       		// We don't have the parent theme, let's install it.
       		$api = themes_api('theme_information', array('slug' => $theme_info->get('Template'), 'fields' => array('sections' => false, 'tags' => false) ) ); //Save on a bit of bandwidth.
   
       		if ( ! $api || is_wp_error($api) ) {
       			$this->skin->feedback( 'parent_theme_not_found', $theme_info->get('Template') );
       			// Don't show activate or preview actions after install
       			add_filter('install_theme_complete_actions', array($this, 'hide_activate_preview_actions') );
       			return $install_result;
       		}
   
       		// Backup required data we're going to override:
       		$child_api = $this->skin->api;
       		$child_success_message = $this->strings['process_success'];
   
       		// Override them
       		$this->skin->api = $api;
       		$this->strings['process_success_specific'] = $this->strings['parent_theme_install_success'];//, $api->name, $api->version);
   
       		$this->skin->feedback('parent_theme_prepare_install', $api->name, $api->version);
   
       		add_filter('install_theme_complete_actions', '__return_false', 999); // Don't show any actions after installing the theme.
   
       		// Install the parent theme
       		$parent_result = $this->run( array(
       			'package' => $api->download_link,
       			'destination' => get_theme_root(),
       			'clear_destination' => false, //Do not overwrite files.
       			'clear_working' => true
       		) );
   
       		if ( is_wp_error($parent_result) )
       			add_filter('install_theme_complete_actions', array($this, 'hide_activate_preview_actions') );
   
       		// Start cleaning up after the parents installation
       		remove_filter('install_theme_complete_actions', '__return_false', 999);
   
       		// Reset child's result and data
       		$this->result = $child_result;
       		$this->skin->api = $child_api;
       		$this->strings['process_success'] = $child_success_message;
   
       		return $install_result;
       	}
   
       	/**
       	 * Don't display the activate and preview actions to the user.
       	 *
       	 * Hooked to the {@see 'install_theme_complete_actions'} filter by
       	 * {@see Theme_Upgrader::check_parent_theme_filter()} when installing
       	 * a child theme and installing the parent theme fails.
       	 *
       	 * @since 3.4.0
       	 * @access public
       	 *
       	 * @param array $actions Preview actions.
       	 * @return array
       	 */
       	public function hide_activate_preview_actions( $actions ) {
       		unset($actions['activate'], $actions['preview']);
       		return $actions;
       	}
   
       	/**
       	 * Install a theme package.
       	 *
       	 * @since 2.8.0
       	 * @since 3.7.0 The <code>$args</code> parameter was added, making clearing the update cache optional.
       	 * @access public
       	 *
       	 * @param string $package The full local path or URI of the package.
       	 * @param array  $args {
       	 *     Optional. Other arguments for installing a theme package. Default empty array.
       	 *
       	 *     @type bool $clear_update_cache Whether to clear the updates cache if successful.
       	 *                                    Default true.
       	 * }
       	 *
       	 * @return bool|WP_Error True if the install was successful, false or a {@see WP_Error} object otherwise.
       	 */
       	public function install( $package, $args = array() ) {
   
       		$defaults = array(
       			'clear_update_cache' => true,
       		);
       		$parsed_args = wp_parse_args( $args, $defaults );
   
       		$this->init();
       		$this->install_strings();
   
       		add_filter('upgrader_source_selection', array($this, 'check_package') );
       		add_filter('upgrader_post_install', array($this, 'check_parent_theme_filter'), 10, 3);
       		// Clear cache so wp_update_themes() knows about the new theme.
       		add_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9, 0 );
   
       		$this->run( array(
       			'package' => $package,
       			'destination' => get_theme_root(),
       			'clear_destination' => false, //Do not overwrite files.
       			'clear_working' => true,
       			'hook_extra' => array(
       				'type' => 'theme',
       				'action' => 'install',
       			),
       		) );
   
       		remove_action( 'upgrader_process_complete', 'wp_clean_themes_cache', 9 );
       		remove_filter('upgrader_source_selection', array($this, 'check_package') );
       		remove_filter('upgrader_post_install', array($this, 'check_parent_theme_filter'));
   
       		if ( ! $this->result || is_wp_error($this->result) )
       			return $this->result;
   
       		// Refresh the Theme Update information
       		wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
   
       		return true;
       	}
   
       	/**
       	 * Upgrade a theme.
       	 *
       	 * @since 2.8.0
       	 * @since 3.7.0 The <code>$args</code> parameter was added, making clearing the update cache optional.
       	 * @access public
       	 *
       	 * @param string $theme The theme slug.
       	 * @param array  $args {
       	 *     Optional. Other arguments for upgrading a theme. Default empty array.
       	 *
       	 *     @type bool $clear_update_cache Whether to clear the update cache if successful.
       	 *                                    Default true.
       	 * }
       	 * @return bool|WP_Error True if the upgrade was successful, false or a {@see WP_Error} object otherwise.
       	 */
       	public function upgrade( $theme, $args = array() ) {
   
       		$defaults = array(
       			'clear_update_cache' => true,
       		);
       		$parsed_args = wp_parse_args( $args, $defaults );
   
       		$this->init();
       		$this->upgrade_strings();
   
       		// Is an update available?
       		$current = get_site_transient( 'update_themes' );
       		if ( !isset( $current->response[ $theme ] ) ) {
       			$this->skin->before();
       			$this->skin->set_result(false);
       			$this->skin->error( 'up_to_date' );
       			$this->skin->after();
       			return false;
       		}
   
       		$r = $current->response[ $theme ];
   
       		add_filter('upgrader_pre_install', array($this, 'current_before'), 10, 2);
       		add_filter('upgrader_post_install', array($this, 'current_after'), 10, 2);
       		add_filter('upgrader_clear_destination', array($this, 'delete_old_theme'), 10, 4);
   
       		$this->run( array(
       			'package' => $r['package'],
       			'destination' => get_theme_root( $theme ),
       			'clear_destination' => true,
       			'clear_working' => true,
       			'hook_extra' => array(
       				'theme' => $theme,
       				'type' => 'theme',
       				'action' => 'update',
       			),
       		) );
   
       		remove_filter('upgrader_pre_install', array($this, 'current_before'));
       		remove_filter('upgrader_post_install', array($this, 'current_after'));
       		remove_filter('upgrader_clear_destination', array($this, 'delete_old_theme'));
   
       		if ( ! $this->result || is_wp_error($this->result) )
       			return $this->result;
   
       		wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
   
       		return true;
       	}
   
       	/**
       	 * Upgrade several themes at once.
       	 *
       	 * @since 3.0.0
       	 * @since 3.7.0 The <code>$args</code> parameter was added, making clearing the update cache optional.
       	 * @access public
       	 *
       	 * @param array $themes The theme slugs.
       	 * @param array $args {
       	 *     Optional. Other arguments for upgrading several themes at once. Default empty array.
       	 *
       	 *     @type bool $clear_update_cache Whether to clear the update cache if successful.
       	 *                                    Default true.
       	 * }
       	 * @return array[]|false An array of results, or false if unable to connect to the filesystem.
       	 */
       	public function bulk_upgrade( $themes, $args = array() ) {
   
       		$defaults = array(
       			'clear_update_cache' => true,
       		);
       		$parsed_args = wp_parse_args( $args, $defaults );
   
       		$this->init();
       		$this->bulk = true;
       		$this->upgrade_strings();
   
       		$current = get_site_transient( 'update_themes' );
   
       		add_filter('upgrader_pre_install', array($this, 'current_before'), 10, 2);
       		add_filter('upgrader_post_install', array($this, 'current_after'), 10, 2);
       		add_filter('upgrader_clear_destination', array($this, 'delete_old_theme'), 10, 4);
   
       		$this->skin->header();
   
       		// Connect to the Filesystem first.
       		$res = $this->fs_connect( array(WP_CONTENT_DIR) );
       		if ( ! $res ) {
       			$this->skin->footer();
       			return false;
       		}
   
       		$this->skin->bulk_header();
   
       		// Only start maintenance mode if:
       		// - running Multisite and there are one or more themes specified, OR
       		// - a theme with an update available is currently in use.
       		// @TODO: For multisite, maintenance mode should only kick in for individual sites if at all possible.
       		$maintenance = ( is_multisite() && ! empty( $themes ) );
       		foreach ( $themes as $theme )
       			$maintenance = $maintenance || $theme == get_stylesheet() || $theme == get_template();
       		if ( $maintenance )
       			$this->maintenance_mode(true);
   
       		$results = array();
   
       		$this->update_count = count($themes);
       		$this->update_current = 0;
       		foreach ( $themes as $theme ) {
       			$this->update_current++;
   
       			$this->skin->theme_info = $this->theme_info($theme);
   
       			if ( !isset( $current->response[ $theme ] ) ) {
       				$this->skin->set_result(true);
       				$this->skin->before();
       				$this->skin->feedback( 'up_to_date' );
       				$this->skin->after();
       				$results[$theme] = true;
       				continue;
       			}
   
       			// Get the URL to the zip file
       			$r = $current->response[ $theme ];
   
       			$result = $this->run( array(
       				'package' => $r['package'],
       				'destination' => get_theme_root( $theme ),
       				'clear_destination' => true,
       				'clear_working' => true,
       				'is_multi' => true,
       				'hook_extra' => array(
       					'theme' => $theme
       				),
       			) );
   
       			$results[$theme] = $this->result;
   
       			// Prevent credentials auth screen from displaying multiple times
       			if ( false === $result )
       				break;
       		} //end foreach $plugins
   
       		$this->maintenance_mode(false);
   
       		/** This action is documented in wp-admin/includes/class-wp-upgrader.php */
       		do_action( 'upgrader_process_complete', $this, array(
       			'action' => 'update',
       			'type' => 'theme',
       			'bulk' => true,
       			'themes' => $themes,
       		) );
   
       		$this->skin->bulk_footer();
   
       		$this->skin->footer();
   
       		// Cleanup our hooks, in case something else does a upgrade on this connection.
       		remove_filter('upgrader_pre_install', array($this, 'current_before'));
       		remove_filter('upgrader_post_install', array($this, 'current_after'));
       		remove_filter('upgrader_clear_destination', array($this, 'delete_old_theme'));
   
       		// Refresh the Theme Update information
       		wp_clean_themes_cache( $parsed_args['clear_update_cache'] );
   
       		return $results;
       	}
   
       	/**
       	 * Check that the package source contains a valid theme.
       	 *
       	 * Hooked to the {@see 'upgrader_source_selection'} filter by {@see Theme_Upgrader::install()}.
       	 * It will return an error if the theme doesn't have style.css or index.php
       	 * files.
       	 *
       	 * @since 3.3.0
       	 * @access public
       	 *
       	 * @global WP_Filesystem_Base $wp_filesystem Subclass
       	 *
       	 * @param s
       ```
   
 *   Forum: [Fixing WordPress](https://wordpress.org/support/forum/how-to-and-troubleshooting/)
   
   In reply to: [auto update not working for wordpress 4.5.3](https://wordpress.org/support/topic/auto-update-not-working-for-wordpress-453/)
 *  Thread Starter [dkomander](https://wordpress.org/support/users/dkomander/)
 * (@dkomander)
 * [9 years, 9 months ago](https://wordpress.org/support/topic/auto-update-not-working-for-wordpress-453/#post-7647600)
 * Hi James,
 * i tried this plugin and set everything to “enable” (except for the development
   releases). I see in the plugins section that all plugins are marked as “updates
   enabled”.
 * I tried a “force autmatic updates” action but appearently, it does not work either.
   I also enabled logging for this plugin and restarted the whole server just in
   case. But still no luck. :-/
 * There seems no logfile in which i can debug the error. Do you have an idea how
   i can debug further?
 * Thanks in advance!

Viewing 5 replies - 1 through 5 (of 5 total)