| 949 | /** |
| 950 | * Send upgrade WP_Error data to WordPress.org. |
| 951 | * |
| 952 | * @since 5.7.0 |
| 953 | * |
| 954 | * @global string $wp_version The WordPress version string. |
| 955 | * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. |
| 956 | * @param WP_Error $result WP_Error data from failed upgrade process. |
| 957 | * @param int $start_time Time that run() started. |
| 958 | * @param string $method Name of method sending data. |
| 959 | * |
| 960 | * @return void |
| 961 | */ |
| 962 | public function send_error_data( $result, $start_time, $method = null ) { |
| 963 | global $wp_version, $wp_filesystem; |
| 964 | |
| 965 | if ( ! is_wp_error( $result ) ) { |
| 966 | return; |
| 967 | } |
| 968 | $stats = array( |
| 969 | 'process' => $method, |
| 970 | 'update_type' => null, |
| 971 | 'name' => null, |
| 972 | 'update_version' => null, |
| 973 | 'success' => false, |
| 974 | 'fs_method' => $wp_filesystem->method, |
| 975 | 'fs_method_forced' => defined( 'FS_METHOD' ) || has_filter( 'filesystem_method' ), |
| 976 | 'fs_method_direct' => ! empty( $GLOBALS['_wp_filesystem_direct_method'] ) ? $GLOBALS['_wp_filesystem_direct_method'] : '', |
| 977 | 'time_taken' => time() - $start_time, |
| 978 | 'wp_version' => $wp_version, |
| 979 | 'error_code' => $result->get_error_code(), |
| 980 | 'error_message' => $result->get_error_message(), |
| 981 | 'error_data' => $result->get_error_data(), |
| 982 | ); |
| 983 | if ( $this instanceof Plugin_Upgrader ) { |
| 984 | if ( isset( $this->skin->plugin_info ) ) { |
| 985 | $stats['update_type'] = 'manual_plugin_update'; |
| 986 | $stats['name'] = $this->skin->plugin_info['Name']; |
| 987 | $stats['update_version'] = $this->skin->plugin_info['Version']; |
| 988 | } else { |
| 989 | $stats['update_type'] = 'automatic_plugin_update'; |
| 990 | } |
| 991 | wp_update_plugins( $stats ); |
| 992 | } |
| 993 | if ( $this instanceof Theme_Upgrader ) { |
| 994 | if ( isset( $this->skin->theme_info )) { |
| 995 | $stats['update_type'] = 'manual_theme_update'; |
| 996 | $stats['name'] = $this->skin->theme_info->get('Name'); |
| 997 | $stats['update_version'] = $this->skin->theme_info->get('Version'); |
| 998 | } else { |
| 999 | $stats['update_type'] = 'automatic_theme_update'; |
| 1000 | } |
| 1001 | wp_update_themes( $stats ); |
| 1002 | } |
| 1003 | } |
| 1004 | |
| 1005 | /** |
| 1006 | * Create a zip archive of the plugin/theme being upgraded into a rollback directory. |
| 1007 | * |
| 1008 | * @since 5.7.0 |
| 1009 | * @uses 'upgrader_pre_install' filter. |
| 1010 | * |
| 1011 | * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. |
| 1012 | * @param bool $true Boolean response to 'upgrader_pre_install' filter. |
| 1013 | * Default is true. |
| 1014 | * @param array $hook_extra Array of data for plugin/theme being updated. |
| 1015 | * |
| 1016 | * @return bool |
| 1017 | */ |
| 1018 | public function zip_to_rollback_dir( $true, $hook_extra ) { |
| 1019 | global $wp_filesystem; |
| 1020 | |
| 1021 | $rollback_dir = $wp_filesystem->wp_content_dir() . 'upgrade/rollback/'; |
| 1022 | $type = key( $hook_extra ); |
| 1023 | $slug = 'plugin' === $type ? dirname( $hook_extra['plugin'] ) : $hook_extra['theme']; |
| 1024 | $src = 'plugin' === $type ? WP_PLUGIN_DIR . "/{$slug}" : get_theme_root(). "/{$slug}"; |
| 1025 | if ( $wp_filesystem->mkdir( $rollback_dir ) ) { |
| 1026 | $path_prefix = strlen( $src ) + 1; |
| 1027 | $zip = new ZipArchive(); |
| 1028 | |
| 1029 | if ( true === $zip->open( "{$rollback_dir}{$slug}.zip", ZipArchive::CREATE | ZipArchive::OVERWRITE ) ) { |
| 1030 | $files = new RecursiveIteratorIterator( |
| 1031 | new RecursiveDirectoryIterator( $src ), |
| 1032 | RecursiveIteratorIterator::LEAVES_ONLY |
| 1033 | ); |
| 1034 | |
| 1035 | foreach ( $files as $name => $file ) { |
| 1036 | // Skip directories (they would be added automatically). |
| 1037 | if ( ! $file->isDir() ) { |
| 1038 | // Get real and relative path for current file. |
| 1039 | $file_path = $file->getRealPath(); |
| 1040 | $relative_path = substr( $file_path, $path_prefix ); |
| 1041 | |
| 1042 | // Add current file to archive. |
| 1043 | $zip->addFile( $file_path, $relative_path ); |
| 1044 | } |
| 1045 | } |
| 1046 | |
| 1047 | $zip->close(); |
| 1048 | } |
| 1049 | } |
| 1050 | |
| 1051 | return $true; |
| 1052 | } |
| 1053 | |
| 1054 | /** |
| 1055 | * Extract zipped rollback to original location. |
| 1056 | * |
| 1057 | * @since 5.7.0 |
| 1058 | * |
| 1059 | * @global WP_Filesystem_Base $wp_filesystem WordPress filesystem subclass. |
| 1060 | * @param string $destination File path of plugin/theme. |
| 1061 | * @param array $hook_extra Array of data for plugin/theme being updated. |
| 1062 | * @param WP_Error $error WP_Error object. |
| 1063 | * |
| 1064 | * @return bool |
| 1065 | */ |
| 1066 | public function extract_rollback( $destination, $hook_extra, $error ) { |
| 1067 | global $wp_filesystem; |
| 1068 | |
| 1069 | $rollback_dir = $wp_filesystem->wp_content_dir() . 'upgrade/rollback/'; |
| 1070 | $type = key( $hook_extra ); |
| 1071 | $slug = 'plugin' === $type ? dirname( $hook_extra['plugin'] ) : $hook_extra['theme']; |
| 1072 | $src = 'plugin' === $type ? WP_PLUGIN_DIR . "/{$slug}" : get_theme_root() . "/{$slug}"; |
| 1073 | $rollback = $rollback_dir . "{$slug}.zip"; |
| 1074 | |
| 1075 | $zip = new \ZipArchive(); |
| 1076 | if ( true === $zip->open( "$rollback", ZipArchive::CHECKCONS ) ) { |
| 1077 | $zip->extractTo( "$destination" ); |
| 1078 | $zip->close(); |
| 1079 | |
| 1080 | return true; |
| 1081 | } |
| 1082 | |
| 1083 | return false; |
| 1084 | } |