+ /**
+ * Clears the directory where this item is going to be installed into.
+ *
+ * @since 4.3.0
+ *
+ * @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
+ *
+ * @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 `WP_Upgrader:$result`), or a {@see WP_Error} on failure.
+ */