5
5
use WP_CLI \Iterators \Table as TableIterator ;
6
6
use WP_CLI \Utils ;
7
7
use WP_CLI \Formatter ;
8
+ use WP_CLI \WpOrgApi ;
8
9
9
10
/**
10
11
* Downloads, installs, updates, and manages a WordPress installation.
@@ -116,6 +117,9 @@ public function check_update( $_, $assoc_args ) {
116
117
* [--force]
117
118
* : Overwrites existing files, if present.
118
119
*
120
+ * [--insecure]
121
+ * : Retry download without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
122
+ *
119
123
* ## EXAMPLES
120
124
*
121
125
* $ wp core download --locale=nl_NL
@@ -153,8 +157,9 @@ public function download( $args, $assoc_args ) {
153
157
WP_CLI ::error ( "' {$ download_dir }' is not writable by current user. " );
154
158
}
155
159
156
- $ locale = Utils \get_flag_value ( $ assoc_args , 'locale ' , 'en_US ' );
157
- $ skip_content = Utils \get_flag_value ( $ assoc_args , 'skip-content ' );
160
+ $ locale = (string ) Utils \get_flag_value ( $ assoc_args , 'locale ' , 'en_US ' );
161
+ $ skip_content = (bool ) Utils \get_flag_value ( $ assoc_args , 'skip-content ' , false );
162
+ $ insecure = (bool ) Utils \get_flag_value ( $ assoc_args , 'insecure ' , false );
158
163
159
164
$ download_url = array_shift ( $ args );
160
165
$ from_url = ! empty ( $ download_url );
@@ -180,12 +185,17 @@ public function download( $args, $assoc_args ) {
180
185
181
186
$ download_url = $ this ->get_download_url ( $ version , $ locale , $ extension );
182
187
} else {
183
- $ offer = $ this ->get_download_offer ( $ locale );
188
+ try {
189
+ $ offer = ( new WpOrgApi ( [ 'insecure ' => $ insecure ] ) )
190
+ ->get_core_download_offer ( $ locale );
191
+ } catch ( Exception $ exception ) {
192
+ WP_CLI ::error ( $ exception );
193
+ }
184
194
if ( ! $ offer ) {
185
195
WP_CLI ::error ( "The requested locale ( {$ locale }) was not found. " );
186
196
}
187
- $ version = $ offer-> current ;
188
- $ download_url = $ offer-> download ;
197
+ $ version = $ offer[ ' current ' ] ;
198
+ $ download_url = $ offer[ ' download ' ] ;
189
199
if ( ! $ skip_content ) {
190
200
$ download_url = str_replace ( '.zip ' , '.tar.gz ' , $ download_url );
191
201
}
@@ -256,6 +266,7 @@ function () use ( $temp ) {
256
266
$ options = [
257
267
'timeout ' => 600 , // 10 minutes ought to be enough for everybody
258
268
'filename ' => $ temp ,
269
+ 'insecure ' => $ insecure ,
259
270
];
260
271
261
272
$ response = Utils \http_request ( 'GET ' , $ download_url , null , $ headers , $ options );
@@ -267,7 +278,8 @@ function () use ( $temp ) {
267
278
}
268
279
269
280
if ( 'nightly ' !== $ version ) {
270
- $ md5_response = Utils \http_request ( 'GET ' , $ download_url . '.md5 ' );
281
+ unset( $ options ['filename ' ] );
282
+ $ md5_response = Utils \http_request ( 'GET ' , $ download_url . '.md5 ' , null , [], $ options );
271
283
if ( $ md5_response ->status_code >= 200 && $ md5_response ->status_code < 300 ) {
272
284
$ md5_file = md5_file ( $ temp );
273
285
@@ -299,37 +311,12 @@ function () use ( $temp ) {
299
311
}
300
312
301
313
if ( $ wordpress_present ) {
302
- $ this ->cleanup_extra_files ( $ from_version , $ version , $ locale );
314
+ $ this ->cleanup_extra_files ( $ from_version , $ version , $ locale, $ insecure );
303
315
}
304
316
305
317
WP_CLI ::success ( 'WordPress downloaded. ' );
306
318
}
307
319
308
- private static function read ( $ url ) {
309
- $ headers = [ 'Accept ' => 'application/json ' ];
310
- $ response = Utils \http_request ( 'GET ' , $ url , null , $ headers , [ 'timeout ' => 30 ] );
311
- if ( 200 === $ response ->status_code ) {
312
- return $ response ->body ;
313
- } else {
314
- WP_CLI ::error ( "Couldn't fetch response from {$ url } (HTTP code {$ response ->status_code }). " );
315
- }
316
- }
317
-
318
- private function get_download_offer ( $ locale ) {
319
- $ out = self ::read ( 'https://api.wordpress.org/core/version-check/1.7/?locale= ' . $ locale );
320
- $ out = function_exists ( 'wp_json_decode ' )
321
- ? wp_json_decode ( $ out )
322
- : json_decode ( $ out );
323
-
324
- $ offer = $ out ->offers [0 ];
325
-
326
- if ( $ offer ->locale !== $ locale ) {
327
- return false ;
328
- }
329
-
330
- return $ offer ;
331
- }
332
-
333
320
/**
334
321
* Checks if WordPress is installed.
335
322
*
@@ -952,16 +939,20 @@ private static function find_var( $var_name, $code ) {
952
939
/**
953
940
* Security copy of the core function with Requests - Gets the checksums for the given version of WordPress.
954
941
*
955
- * @param string $version Version string to query.
956
- * @param string $locale Locale to query.
942
+ * @param string $version Version string to query.
943
+ * @param string $locale Locale to query.
944
+ * @param bool $insecure Whether to retry without certificate validation on TLS handshake failure.
957
945
* @return string|array String message on failure. An array of checksums on success.
958
946
*/
959
- private static function get_core_checksums ( $ version , $ locale ) {
947
+ private static function get_core_checksums ( $ version , $ locale, $ insecure ) {
960
948
$ query = http_build_query ( compact ( 'version ' , 'locale ' ), null , '& ' );
961
949
$ url = "https://api.wordpress.org/core/checksums/1.0/? {$ query }" ;
962
950
963
- $ options = [ 'timeout ' => 30 ];
964
951
$ headers = [ 'Accept ' => 'application/json ' ];
952
+ $ options = [
953
+ 'timeout ' => 30 ,
954
+ 'insecure ' => $ insecure ,
955
+ ];
965
956
966
957
$ response = Utils \http_request ( 'GET ' , $ url , null , $ headers , $ options );
967
958
@@ -1007,6 +998,9 @@ private static function get_core_checksums( $version, $locale ) {
1007
998
* [--locale=<locale>]
1008
999
* : Select which language you want to download.
1009
1000
*
1001
+ * [--insecure]
1002
+ * : Retry download without certificate validation if TLS handshake fails. Note: This makes the request vulnerable to a MITM attack.
1003
+ *
1010
1004
* ## EXAMPLES
1011
1005
*
1012
1006
* # Update WordPress
@@ -1043,7 +1037,6 @@ public function update( $args, $assoc_args ) {
1043
1037
global $ wp_version ;
1044
1038
1045
1039
$ update = null ;
1046
- $ from_api = null ;
1047
1040
$ upgrader = 'WP_CLI \\Core \\CoreUpgrader ' ;
1048
1041
1049
1042
if ( 'trunk ' === Utils \get_flag_value ( $ assoc_args , 'version ' ) ) {
@@ -1094,7 +1087,7 @@ public function update( $args, $assoc_args ) {
1094
1087
list ( $ update ) = $ from_api ->updates ;
1095
1088
}
1096
1089
}
1097
- } elseif ( \ WP_CLI \ Utils \wp_version_compare ( $ assoc_args ['version ' ], '< ' )
1090
+ } elseif ( Utils \wp_version_compare ( $ assoc_args ['version ' ], '< ' )
1098
1091
|| 'nightly ' === $ assoc_args ['version ' ]
1099
1092
|| Utils \get_flag_value ( $ assoc_args , 'force ' ) ) {
1100
1093
@@ -1133,9 +1126,10 @@ public function update( $args, $assoc_args ) {
1133
1126
}
1134
1127
1135
1128
$ from_version = $ wp_version ;
1129
+ $ insecure = (bool ) Utils \get_flag_value ( $ assoc_args , 'insecure ' , false );
1136
1130
1137
1131
$ GLOBALS ['wpcli_core_update_obj ' ] = $ update ;
1138
- $ result = Utils \get_upgrader ( $ upgrader )->upgrade ( $ update );
1132
+ $ result = Utils \get_upgrader ( $ upgrader, $ insecure )->upgrade ( $ update );
1139
1133
unset( $ GLOBALS ['wpcli_core_update_obj ' ] );
1140
1134
1141
1135
if ( is_wp_error ( $ result ) ) {
@@ -1153,8 +1147,8 @@ public function update( $args, $assoc_args ) {
1153
1147
$ to_version = $ wp_details ['wp_version ' ];
1154
1148
}
1155
1149
1156
- $ locale = Utils \get_flag_value ( $ assoc_args , 'locale ' , get_locale () );
1157
- $ this ->cleanup_extra_files ( $ from_version , $ to_version , $ locale );
1150
+ $ locale = ( string ) Utils \get_flag_value ( $ assoc_args , 'locale ' , get_locale () );
1151
+ $ this ->cleanup_extra_files ( $ from_version , $ to_version , $ locale, $ insecure );
1158
1152
1159
1153
WP_CLI ::success ( 'WordPress updated successfully. ' );
1160
1154
}
@@ -1347,18 +1341,26 @@ private function get_updates( $assoc_args ) {
1347
1341
return array_values ( $ updates );
1348
1342
}
1349
1343
1350
- private function cleanup_extra_files ( $ version_from , $ version_to , $ locale ) {
1344
+ /**
1345
+ * Clean up extra files.
1346
+ *
1347
+ * @param string $version_from Starting version that the installation was updated from.
1348
+ * @param string $version_to Target version that the installation is updated to.
1349
+ * @param string $locale Locale of the installation.
1350
+ * @param bool $insecure Whether to retry without certificate validation on TLS handshake failure.
1351
+ */
1352
+ private function cleanup_extra_files ( $ version_from , $ version_to , $ locale , $ insecure ) {
1351
1353
if ( ! $ version_from || ! $ version_to ) {
1352
1354
WP_CLI ::warning ( 'Failed to find WordPress version. Please cleanup files manually. ' );
1353
1355
return ;
1354
1356
}
1355
1357
1356
- $ old_checksums = self ::get_core_checksums ( $ version_from , $ locale ?: 'en_US ' );
1358
+ $ old_checksums = self ::get_core_checksums ( $ version_from , $ locale ?: 'en_US ' , $ insecure );
1357
1359
if ( ! is_array ( $ old_checksums ) ) {
1358
1360
WP_CLI ::warning ( "{$ old_checksums } Please cleanup files manually. " );
1359
1361
return ;
1360
1362
}
1361
- $ new_checksums = self ::get_core_checksums ( $ version_to , $ locale ?: 'en_US ' );
1363
+ $ new_checksums = self ::get_core_checksums ( $ version_to , $ locale ?: 'en_US ' , $ insecure );
1362
1364
if ( ! is_array ( $ new_checksums ) ) {
1363
1365
WP_CLI ::warning ( "{$ new_checksums } Please cleanup files manually. " );
1364
1366
return ;
0 commit comments