PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
← All changes | class.jetpack-cli.php +133 -91 13.4.5 → 16.3-a.7 View file →
@@ -9,8 +9,9 @@
9 9 use Automattic\Jetpack\Connection\Manager as Connection_Manager;
10 10 use Automattic\Jetpack\Connection\Tokens;
11 11 use Automattic\Jetpack\Identity_Crisis;
12 12 use Automattic\Jetpack\IP\Utils as IP_Utils;
13 +use Automattic\Jetpack\Publicize\Connections;
13 14 use Automattic\Jetpack\Publicize\Publicize;
14 15 use Automattic\Jetpack\Status;
15 16 use Automattic\Jetpack\Sync\Actions;
16 17 use Automattic\Jetpack\Sync\Listener;
@@ -85,9 +86,9 @@
85 86 }
86 87
87 88 $master_user_email = Jetpack::get_master_user_email();
88 89
89 - $cxntests = new Jetpack_Cxn_Tests();
90 + $cxntests = new Automattic\Jetpack\Connection\Connection_Health_Tests();
90 91
91 92 if ( $cxntests->pass() ) {
92 93 $cxntests->output_results_for_cli();
93 94
@@ -230,9 +231,9 @@
230 231 WP_CLI::success( __( 'The site is not currently connected, so nothing to do!', 'jetpack' ) );
231 232 return;
232 233 }
233 234
234 - $action = isset( $args[0] ) ? $args[0] : 'prompt';
235 + $action = $args[0] ?? 'prompt';
235 236 if ( ! in_array( $action, array( 'blog', 'user', 'prompt' ), true ) ) {
236 237 /* translators: %s is a command like "prompt" */
237 238 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
238 239 }
@@ -324,9 +325,9 @@
324 325 * @param array $args Positional args.
325 326 * @param array $assoc_args Named args.
326 327 */
327 328 public function reset( $args, $assoc_args ) {
328 - $action = isset( $args[0] ) ? $args[0] : 'prompt';
329 + $action = $args[0] ?? 'prompt';
329 330 if ( ! in_array( $action, array( 'options', 'modules', 'sync-checksum' ), true ) ) {
330 331 /* translators: %s is a command like "prompt" */
331 332 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
332 333 }
@@ -545,9 +546,9 @@
545 546 * @param array $assoc_args Named args.
546 547 */
547 548 public function module( $args, $assoc_args ) {
548 549 $module_slug = null;
549 - $action = isset( $args[0] ) ? $args[0] : 'list';
550 + $action = $args[0] ?? 'list';
550 551
551 552 if ( isset( $args[1] ) ) {
552 553 $module_slug = $args[1];
553 554 if ( 'all' !== $module_slug && ! Jetpack::is_module( $module_slug ) ) {
@@ -590,8 +591,12 @@
590 591 case 'activate':
591 592 $module = Jetpack::get_module( $module_slug );
592 593 Jetpack::log( 'activate', $module_slug );
593 594 if ( Jetpack::activate_module( $module_slug, false, false ) ) {
595 + if ( ! Jetpack::is_module_active( $module_slug ) ) {
596 + /* translators: %s is the name of a Jetpack module */
597 + WP_CLI::error( sprintf( __( '%s is disabled by your host or site administrator, so it stays off.', 'jetpack' ), $module['name'] ) );
598 + }
594 599 /* translators: %s is the name of a Jetpack module */
595 600 WP_CLI::success( sprintf( __( '%s has been activated.', 'jetpack' ), $module['name'] ) );
596 601 } else {
597 602 /* translators: %s is the name of a Jetpack module */
@@ -606,8 +611,12 @@
606 611 case 'deactivate':
607 612 $module = Jetpack::get_module( $module_slug );
608 613 Jetpack::log( 'deactivate', $module_slug );
609 614 Jetpack::deactivate_module( $module_slug );
615 + if ( Jetpack::is_module_active( $module_slug ) ) {
616 + /* translators: %s is the name of a Jetpack module */
617 + WP_CLI::error( sprintf( __( '%s is enabled by your host or site administrator, so it stays on.', 'jetpack' ), $module['name'] ) );
618 + }
610 619 /* translators: %s is the name of a Jetpack module */
611 620 WP_CLI::success( sprintf( __( '%s has been deactivated.', 'jetpack' ), $module['name'] ) );
612 621 break;
613 622 case 'deactivate_all':
@@ -638,9 +647,9 @@
638 647 *
639 648 * @param array $args Positional args.
640 649 */
641 650 public function protect( $args ) {
642 - $action = isset( $args[0] ) ? $args[0] : 'prompt';
651 + $action = $args[0] ?? 'prompt';
643 652 if ( ! in_array( $action, array( 'whitelist', 'allow' ), true ) ) { // Still allow "whitelist" for legacy support.
644 653 /* translators: %s is a command like "prompt" */
645 654 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
646 655 }
@@ -767,9 +776,9 @@
767 776 *
768 777 * @param array $args Positional args.
769 778 */
770 779 public function options( $args ) {
771 - $action = isset( $args[0] ) ? $args[0] : 'list';
780 + $action = $args[0] ?? 'list';
772 781 $safe_to_modify = Jetpack_Options::get_options_for_reset();
773 782
774 783 // Is the option flagged as unsafe?
775 784 $flagged = ! in_array( $args[1], $safe_to_modify, true );
@@ -893,9 +902,9 @@
893 902 * @param array $assoc_args Named args.
894 903 */
895 904 public function sync( $args, $assoc_args ) {
896 905
897 - $action = isset( $args[0] ) ? $args[0] : 'status';
906 + $action = $args[0] ?? 'status';
898 907
899 908 switch ( $action ) {
900 909 case 'status':
901 910 $status = Actions::get_sync_status();
@@ -902,9 +911,9 @@
902 911 $collection = array();
903 912 foreach ( $status as $key => $item ) {
904 913 $collection[] = array(
905 914 'option' => $key,
906 - 'value' => is_scalar( $item ) ? $item : wp_json_encode( $item ),
915 + 'value' => is_scalar( $item ) ? $item : wp_json_encode( $item, JSON_UNESCAPED_SLASHES ),
907 916 );
908 917 }
909 918 WP_CLI::log( __( 'Sync Status:', 'jetpack' ) );
910 919 WP_CLI\Utils\format_items( 'table', $collection, array( 'option', 'value' ) );
@@ -914,9 +923,9 @@
914 923 $settings = array();
915 924 foreach ( Settings::get_settings() as $setting => $item ) {
916 925 $settings[] = array(
917 926 'setting' => $setting,
918 - 'value' => is_scalar( $item ) ? $item : wp_json_encode( $item ),
927 + 'value' => is_scalar( $item ) ? $item : wp_json_encode( $item, JSON_UNESCAPED_SLASHES ),
919 928 );
920 929 }
921 930 WP_CLI\Utils\format_items( 'table', $settings, array( 'setting', 'value' ) );
922 931 break;
@@ -984,10 +993,10 @@
984 993 if ( $status->is_offline_mode() ) {
985 994 WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in offline mode.', 'jetpack' ) );
986 995 return;
987 996 }
988 - if ( $status->is_staging_site() ) {
989 - WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in staging mode.', 'jetpack' ) );
997 + if ( $status->in_safe_mode() ) {
998 + WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in safe mode.', 'jetpack' ) );
990 999 return;
991 1000 }
992 1001 }
993 1002 // Get the original settings so that we can restore them later.
@@ -1034,11 +1043,11 @@
1034 1043 $modules = null;
1035 1044 }
1036 1045
1037 1046 // Kick off a full sync.
1038 - if ( Actions::do_full_sync( $modules ) ) {
1047 + if ( Actions::do_full_sync( $modules, 'jetpack_cli' ) ) {
1039 1048 if ( $modules ) {
1040 - /* translators: %s is a comma separated list of Jetpack modules */
1049 + /* translators: %s is a comma-separated list of Jetpack modules */
1041 1050 WP_CLI::log( sprintf( __( 'Initialized a new full sync with modules: %s', 'jetpack' ), implode( ', ', array_keys( $modules ) ) ) );
1042 1051 } else {
1043 1052 WP_CLI::log( __( 'Initialized a new full sync', 'jetpack' ) );
1044 1053 }
@@ -1047,9 +1056,9 @@
1047 1056 // Reset sync settings to original.
1048 1057 Settings::update_settings( $original_settings );
1049 1058
1050 1059 if ( $modules ) {
1051 - /* translators: %s is a comma separated list of Jetpack modules */
1060 + /* translators: %s is a comma-separated list of Jetpack modules */
1052 1061 WP_CLI::error( sprintf( __( 'Could not start a new full sync with modules: %s', 'jetpack' ), implode( ', ', $modules ) ) );
1053 1062 } else {
1054 1063 WP_CLI::error( __( 'Could not start a new full sync', 'jetpack' ) );
1055 1064 }
@@ -1072,9 +1081,9 @@
1072 1081 WP_CLI::log( __( 'Sent more data to WordPress.com', 'jetpack' ) );
1073 1082 }
1074 1083
1075 1084 // Immediate Full Sync does not wait for WP.com to process data so we need to enforce a wait.
1076 - if ( str_contains( get_class( Modules::get_module( 'full-sync' ) ), 'Full_Sync_Immediately' ) ) {
1085 + if ( Modules::get_module( 'full-sync' ) instanceof \Automattic\Jetpack\Sync\Modules\Full_Sync_Immediately ) {
1077 1086 sleep( 15 );
1078 1087 }
1079 1088 }
1080 1089 ++$i;
@@ -1107,10 +1116,10 @@
1107 1116 if ( ! Actions::sync_allowed() ) {
1108 1117 WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site.', 'jetpack' ) );
1109 1118 }
1110 1119
1111 - $queue_name = isset( $args[0] ) ? $args[0] : 'sync';
1112 - $action = isset( $args[1] ) ? $args[1] : 'peek';
1120 + $queue_name = $args[0] ?? 'sync';
1121 + $action = $args[1] ?? 'peek';
1113 1122
1114 1123 // We map the queue name that way we can support more friendly queue names in the commands, but still use
1115 1124 // the queue name that the code expects.
1116 1125 $allowed_queues = array(
@@ -1117,9 +1126,9 @@
1117 1126 'incremental' => 'sync',
1118 1127 'full' => 'full_sync',
1119 1128 );
1120 1129 $queue_name_map = $allowed_queues;
1121 - $mapped_queue_name = isset( $queue_name_map[ $queue_name ] ) ? $queue_name_map[ $queue_name ] : $queue_name;
1130 + $mapped_queue_name = $queue_name_map[ $queue_name ] ?? $queue_name;
1122 1131
1123 1132 switch ( $action ) {
1124 1133 case 'peek':
1125 1134 $queue = new Queue( $mapped_queue_name );
@@ -1132,9 +1141,9 @@
1132 1141 $collection = array();
1133 1142 foreach ( $items as $item ) {
1134 1143 $collection[] = array(
1135 1144 'action' => $item[0],
1136 - 'args' => wp_json_encode( $item[1] ),
1145 + 'args' => wp_json_encode( $item[1], JSON_UNESCAPED_SLASHES ),
1137 1146 'current_user_id' => $item[2],
1138 1147 'microtime' => $item[3],
1139 1148 'importing' => (string) $item[4],
1140 1149 );
@@ -1190,9 +1199,9 @@
1190 1199 if ( Identity_Crisis::validate_sync_error_idc_option() ) {
1191 1200 $this->partner_provision_error(
1192 1201 new WP_Error(
1193 1202 'site_in_safe_mode',
1194 - esc_html__( 'Can not cancel a plan while in safe mode. See: https://jetpack.com/support/safe-mode/', 'jetpack' )
1203 + esc_html__( 'Cannot cancel a plan while in safe mode. See: https://jetpack.com/support/safe-mode/', 'jetpack' )
1195 1204 )
1196 1205 );
1197 1206 }
1198 1207
@@ -1216,12 +1225,11 @@
1216 1225 if ( ! empty( $named_args ) && ! empty( $named_args['partner_tracking_id'] ) ) {
1217 1226 $url = esc_url_raw( add_query_arg( 'partner_tracking_id', $named_args['partner_tracking_id'], $url ) );
1218 1227 }
1219 1228
1229 + // @phan-suppress-next-line PhanAccessMethodInternal -- Phan is correct, but the usage is intentional.
1220 1230 $result = Client::_wp_remote_request( $url, $request );
1221 1231
1222 - Jetpack_Options::delete_option( 'onboarding' );
1223 -
1224 1232 if ( is_wp_error( $result ) ) {
1225 1233 $this->partner_provision_error( $result );
1226 1234 }
1227 1235
@@ -1242,10 +1250,8 @@
1242 1250 * [--wpcom_user_id=<user_id>]
1243 1251 * : WordPress.com ID of user to connect as (must be whitelisted against partner key)
1244 1252 * [--wpcom_user_email=<wpcom_user_email>]
1245 1253 * : Override the email we send to WordPress.com for registration
1246 - * [--onboarding=<onboarding>]
1247 - * : Guide the user through an onboarding wizard
1248 1254 * [--force_register=<register>]
1249 1255 * : Whether to force a site to register
1250 1256 * [--force_connect=<force_connect>]
1251 1257 * : Force JPS to not reuse existing credentials
@@ -1260,9 +1266,9 @@
1260 1266 *
1261 1267 * $ wp jetpack partner_provision '{ some: "json" }' premium 1
1262 1268 * { success: true }
1263 1269 *
1264 - * @synopsis <token_json> [--wpcom_user_id=<user_id>] [--plan=<plan_name>] [--onboarding=<onboarding>] [--force_register=<register>] [--force_connect=<force_connect>] [--home_url=<home_url>] [--site_url=<site_url>] [--wpcom_user_email=<wpcom_user_email>] [--partner_tracking_id=<partner_tracking_id>]
1270 + * @synopsis <token_json> [--wpcom_user_id=<user_id>] [--plan=<plan_name>] [--force_register=<register>] [--force_connect=<force_connect>] [--home_url=<home_url>] [--site_url=<site_url>] [--wpcom_user_email=<wpcom_user_email>] [--partner_tracking_id=<partner_tracking_id>]
1265 1271 *
1266 1272 * @param array $args Positional args.
1267 1273 * @param array $named_args Named args.
1268 1274 */
@@ -1275,11 +1281,9 @@
1275 1281 $this->partner_provision_error( new WP_Error( 'missing_access_token', sprintf( __( 'Invalid token JSON: %s', 'jetpack' ), $token_json ) ) );
1276 1282 }
1277 1283
1278 1284 if ( isset( $token->error ) ) {
1279 - $message = isset( $token->message )
1280 - ? $token->message
1281 - : '';
1285 + $message = $token->message ?? '';
1282 1286 $this->partner_provision_error( new WP_Error( $token->error, $message ) );
1283 1287 }
1284 1288
1285 1289 if ( ! isset( $token->access_token ) ) {
@@ -1296,15 +1300,16 @@
1296 1300 array(
1297 1301 'success' => false,
1298 1302 'error_code' => $body_json->get_error_code(),
1299 1303 'error_message' => $body_json->get_error_message(),
1300 - )
1304 + ),
1305 + JSON_UNESCAPED_SLASHES
1301 1306 )
1302 1307 );
1303 1308 exit( 1 );
1304 1309 }
1305 1310
1306 - WP_CLI::log( wp_json_encode( $body_json ) );
1311 + WP_CLI::log( wp_json_encode( $body_json, JSON_UNESCAPED_SLASHES ) );
1307 1312 }
1308 1313
1309 1314 /**
1310 1315 * Manages your Jetpack sitemap
@@ -1312,23 +1317,23 @@
1312 1317 * ## OPTIONS
1313 1318 *
1314 1319 * rebuild : Rebuild all sitemaps
1315 1320 * --purge : if set, will remove all existing sitemap data before rebuilding
1321 + * --monitor : if set, will output elapsed time, peak memory usage, CPU time (user/system), and average CPU utilization
1322 + * --suspend-cache-addition : if set, will suspend cache additions during sitemap generation
1316 1323 *
1317 1324 * ## EXAMPLES
1318 1325 *
1319 1326 * wp jetpack sitemap rebuild
1327 + * wp jetpack sitemap rebuild --monitor
1320 1328 *
1321 1329 * @subcommand sitemap
1322 - * @synopsis <rebuild> [--purge]
1330 + * @synopsis <rebuild> [--purge] [--monitor] [--suspend-cache-addition]
1323 1331 *
1324 1332 * @param array $args Positional args.
1325 1333 * @param array $assoc_args Named args.
1326 1334 */
1327 1335 public function sitemap( $args, $assoc_args ) {
1328 - if ( ! Jetpack::is_connection_ready() ) {
1329 - WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1330 - }
1331 1336 if ( ! Jetpack::is_module_active( 'sitemaps' ) ) {
1332 1337 WP_CLI::error( __( 'Jetpack Sitemaps module is not currently active. Activate it first if you want to work with sitemaps.', 'jetpack' ) );
1333 1338 }
1334 1339 if ( ! class_exists( 'Jetpack_Sitemap_Builder' ) ) {
@@ -1334,15 +1339,65 @@
1334 1339 if ( ! class_exists( 'Jetpack_Sitemap_Builder' ) ) {
1335 1340 WP_CLI::error( __( 'Jetpack Sitemaps module is active, but unavailable. This can happen if your site is set to discourage search engine indexing. Please enable search engine indexing to allow sitemap generation.', 'jetpack' ) );
1336 1341 }
1337 1342
1343 + if ( isset( $assoc_args['suspend-cache-addition'] ) && $assoc_args['suspend-cache-addition'] ) {
1344 + add_filter( 'jetpack_sitemap_suspend_cache_addition', '__return_true' );
1345 + WP_CLI::success( 'Suspending cache addition.' );
1346 + }
1347 +
1348 + $monitor = isset( $assoc_args['monitor'] ) && $assoc_args['monitor'];
1349 +
1350 + if ( $monitor ) {
1351 + $start_time = microtime( true );
1352 + $rusage_start = function_exists( 'getrusage' ) ? getrusage() : null;
1353 + }
1354 +
1338 1355 if ( isset( $assoc_args['purge'] ) && $assoc_args['purge'] ) {
1339 1356 $librarian = new Jetpack_Sitemap_Librarian();
1340 1357 $librarian->delete_all_stored_sitemap_data();
1358 +
1359 + // Clear sitemap-related transients
1360 + delete_transient( 'jetpack_news_sitemap_xml' );
1361 + delete_transient( 'jetpack-sitemap-state-lock' );
1362 + WP_CLI::success( __( 'Purged all sitemap data and cleared sitemap transients.', 'jetpack' ) );
1341 1363 }
1342 1364
1343 1365 $sitemap_builder = new Jetpack_Sitemap_Builder();
1344 1366 $sitemap_builder->update_sitemap();
1367 +
1368 + WP_CLI::success( __( 'Sitemap rebuilt successfully.', 'jetpack' ) );
1369 +
1370 + if ( $monitor && isset( $start_time ) ) {
1371 + $end_time = microtime( true );
1372 + $peak_memory = memory_get_peak_usage();
1373 + $elapsed_time = $end_time - $start_time;
1374 + $rusage_end = function_exists( 'getrusage' ) ? getrusage() : null;
1375 +
1376 + WP_CLI::log( '----------------------------------' );
1377 + WP_CLI::log( __( 'Performance Metrics:', 'jetpack' ) );
1378 + /* translators: %s is a float representing seconds */
1379 + WP_CLI::log( sprintf( __( 'Elapsed Time: %.4f seconds', 'jetpack' ), $elapsed_time ) );
1380 + /* translators: %s is a human-readable memory size (e.g., 128MB) */
1381 + WP_CLI::log( sprintf( __( 'Peak Memory Usage: %s', 'jetpack' ), size_format( $peak_memory ) ) );
1382 +
1383 + if ( ! empty( $rusage_start ) && ! empty( $rusage_end ) ) {
1384 + $user_cpu_time = ( $rusage_end['ru_utime.tv_sec'] * 1e6 + $rusage_end['ru_utime.tv_usec'] ) - ( $rusage_start['ru_utime.tv_sec'] * 1e6 + $rusage_start['ru_utime.tv_usec'] );
1385 + $system_cpu_time = ( $rusage_end['ru_stime.tv_sec'] * 1e6 + $rusage_end['ru_stime.tv_usec'] ) - ( $rusage_start['ru_stime.tv_sec'] * 1e6 + $rusage_start['ru_stime.tv_usec'] );
1386 +
1387 + /* translators: %d is an integer representing microseconds */
1388 + WP_CLI::log( sprintf( __( 'CPU time (user): %d microseconds', 'jetpack' ), $user_cpu_time ) );
1389 + /* translators: %d is an integer representing microseconds */
1390 + WP_CLI::log( sprintf( __( 'CPU time (system): %d microseconds', 'jetpack' ), $system_cpu_time ) );
1391 +
1392 + // Average CPU utilization over the elapsed wall time.
1393 + $total_cpu_sec = ( $user_cpu_time + $system_cpu_time ) / 1e6;
1394 + $avg_cpu_pct = $elapsed_time > 0 ? ( $total_cpu_sec / $elapsed_time ) * 100 : 0.0;
1395 + /* translators: %s is a percentage like 83.4 */
1396 + WP_CLI::log( sprintf( __( 'Average CPU Utilization: %.1f%%', 'jetpack' ), $avg_cpu_pct ) );
1397 + }
1398 + WP_CLI::log( '----------------------------------' );
1399 + }
1345 1400 }
1346 1401
1347 1402 /**
1348 1403 * Allows authorizing a user via the command line and will activate
@@ -1369,9 +1424,9 @@
1369 1424 $current_user_id = get_current_user_id();
1370 1425
1371 1426 ( new Tokens() )->update_user_token( $current_user_id, sprintf( '%s.%d', $named_args['token'], $current_user_id ), $is_connection_owner );
1372 1427
1373 - WP_CLI::log( wp_json_encode( $named_args ) );
1428 + WP_CLI::log( wp_json_encode( $named_args, JSON_UNESCAPED_SLASHES ) );
1374 1429
1375 1430 if ( $is_connection_owner ) {
1376 1431 /**
1377 1432 * Auto-enable SSO module for new Jetpack Start connections
@@ -1484,9 +1539,9 @@
1484 1539 $output = wp_remote_retrieve_body( $response );
1485 1540 if ( isset( $named_args['pretty'] ) ) {
1486 1541 $decoded_output = json_decode( $output );
1487 1542 if ( $decoded_output ) {
1488 - $output = wp_json_encode( $decoded_output, JSON_PRETTY_PRINT );
1543 + $output = wp_json_encode( $decoded_output, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT );
1489 1544 }
1490 1545 }
1491 1546
1492 1547 if ( isset( $named_args['strip-success'] ) ) {
@@ -1572,9 +1627,9 @@
1572 1627 array(
1573 1628 'resource' => '/activity-log/%d/update-credentials',
1574 1629 'method' => 'POST',
1575 1630 'api_version' => '1.1',
1576 - 'body' => wp_json_encode( $values ),
1631 + 'body' => wp_json_encode( $values, JSON_UNESCAPED_SLASHES ),
1577 1632 'timeout' => 30,
1578 1633 ),
1579 1634 $named_args
1580 1635 );
@@ -1671,8 +1726,11 @@
1671 1726 *
1672 1727 * [<identifier>]
1673 1728 * : The connection ID or service to perform an action on.
1674 1729 *
1730 + * [--ignore-cache]
1731 + * : Whether to ignore connections cache.
1732 + *
1675 1733 * [--format=<format>]
1676 1734 * : Allows overriding the output of the command when listing connections.
1677 1735 * ---
1678 1736 * default: table
@@ -1689,8 +1747,11 @@
1689 1747 *
1690 1748 * # List all publicize connections.
1691 1749 * $ wp jetpack publicize list
1692 1750 *
1751 + * # List all publicize connections, ignoring the cache.
1752 + * $ wp jetpack publicize list --ignore-cache
1753 + *
1693 1754 * # List publicize connections for a given service.
1694 1755 * $ wp jetpack publicize list linkedin
1695 1756 *
1696 1757 * # List all publicize connections for a given user.
@@ -1725,9 +1786,8 @@
1725 1786
1726 1787 if ( ( new Status() )->is_offline_mode() ) {
1727 1788 if (
1728 1789 ! defined( 'JETPACK_DEV_DEBUG' ) &&
1729 - ! has_filter( 'jetpack_development_mode' ) &&
1730 1790 ! has_filter( 'jetpack_offline_mode' ) &&
1731 1791 ! str_contains( site_url(), '.' )
1732 1792 ) {
1733 1793 WP_CLI::error( __( "Jetpack is current in offline mode because the site url does not contain a '.', which often occurs when dynamically setting the WP_SITEURL constant. While in offline mode, the Jetpack Social module will not load.", 'jetpack' ) );
@@ -1747,30 +1807,23 @@
1747 1807 $id_is_service = in_array( $identifier, $services, true );
1748 1808
1749 1809 switch ( $action ) {
1750 1810 case 'list':
1751 - $connections_to_return = array();
1752 -
1811 + $_args = array(
1812 + 'ignore_cache' => $named_args['ignore-cache'] ?? false,
1813 + );
1753 1814 // For the CLI command, let's return all connections when a user isn't specified. This
1754 1815 // differs from the logic in the Publicize class.
1755 - $option_connections = is_user_logged_in()
1756 - ? (array) $publicize->get_all_connections_for_user()
1757 - : (array) $publicize->get_all_connections();
1816 + $connections_to_return = is_user_logged_in()
1817 + ? Connections::get_all_for_user( $_args )
1818 + : Connections::get_all( $_args );
1758 1819
1759 - foreach ( $option_connections as $service_name => $connections ) {
1760 - foreach ( (array) $connections as $id => $connection ) {
1761 - $connection['id'] = $id;
1762 - $connection['service'] = $service_name;
1763 - $connections_to_return[] = $connection;
1764 - }
1765 - }
1766 -
1767 1820 if ( $id_is_service && ! empty( $identifier ) && ! empty( $connections_to_return ) ) {
1768 1821 $temp_connections = $connections_to_return;
1769 1822 $connections_to_return = array();
1770 1823
1771 1824 foreach ( $temp_connections as $connection ) {
1772 - if ( $identifier === $connection['service'] ) {
1825 + if ( $identifier === $connection['service_name'] ) {
1773 1826 $connections_to_return[] = $connection;
1774 1827 }
1775 1828 }
1776 1829 }
@@ -1775,27 +1828,22 @@
1775 1828 }
1776 1829 }
1777 1830
1778 1831 if ( $identifier && ! $id_is_service && ! empty( $connections_to_return ) ) {
1779 - $connections_to_return = wp_list_filter( $connections_to_return, array( 'id' => $identifier ) );
1832 + $connections_to_return = wp_list_filter( $connections_to_return, array( 'connection_id' => $identifier ) );
1780 1833 }
1781 1834
1782 1835 $expected_keys = array(
1783 - 'id',
1784 - 'service',
1785 - 'user_id',
1786 - 'provider',
1787 - 'issued',
1788 - 'expires',
1836 + 'connection_id',
1837 + 'service_name',
1838 + 'display_name',
1789 1839 'external_id',
1790 - 'external_name',
1791 - 'external_display',
1792 - 'type',
1793 - 'connection_data',
1840 + 'wpcom_user_id',
1841 + 'shared',
1794 1842 );
1795 1843
1796 1844 // Somehow, a test site ended up in a state where $connections_to_return looked like:
1797 - // array( array( array( 'id' => 0, 'service' => 0 ) ) ) // phpcs:ignore Squiz.PHP.CommentedOutCode.Found
1845 + // array( array( array( 'id' => 0, 'service' => 0 ) ) )
1798 1846 // This caused the CLI command to error when running WP_CLI\Utils\format_items() below. So
1799 1847 // to minimize future issues, this nested loop will remove any connections that don't contain
1800 1848 // any keys that we expect.
1801 1849 foreach ( (array) $connections_to_return as $connection_key => $connection ) {
@@ -1829,23 +1877,15 @@
1829 1877 }
1830 1878
1831 1879 jetpack_cli_are_you_sure();
1832 1880
1833 - $connections = array();
1834 1881 $service = $identifier;
1882 + $connections = is_user_logged_in()
1883 + ? Connections::get_all_for_user()
1884 + : Connections::get_all();
1835 1885
1836 - $option_connections = is_user_logged_in()
1837 - ? (array) $publicize->get_all_connections_for_user()
1838 - : (array) $publicize->get_all_connections();
1839 -
1840 - if ( 'all' === $service ) {
1841 - foreach ( (array) $option_connections as $service_name => $service_connections ) {
1842 - foreach ( $service_connections as $id => $connection ) {
1843 - $connections[ $id ] = $connection;
1844 - }
1845 - }
1846 - } elseif ( ! empty( $option_connections[ $service ] ) ) {
1847 - $connections = $option_connections[ $service ];
1886 + if ( 'all' !== $service ) {
1887 + $connections = wp_list_filter( $connections, array( 'service_name' => $service ) );
1848 1888 }
1849 1889
1850 1890 if ( ! empty( $connections ) ) {
1851 1891 $count = is_countable( $connections ) ? count( $connections ) : 0;
@@ -1854,9 +1894,10 @@
1854 1894 sprintf( __( 'Disconnecting all connections to %s.', 'jetpack' ), $service ),
1855 1895 $count
1856 1896 );
1857 1897
1858 - foreach ( $connections as $id => $connection ) {
1898 + foreach ( $connections as $connection ) {
1899 + $id = $connection['connection_id'];
1859 1900 if ( false === $publicize->disconnect( false, $id ) ) {
1860 1901 WP_CLI::error(
1861 1902 sprintf(
1862 1903 /* translators: %1$d is a numeric ID and %2$s is a lowercase string for a social network. */
@@ -1865,11 +1906,13 @@
1865 1906 )
1866 1907 );
1867 1908 }
1868 1909
1910 + // @phan-suppress-next-line PhanUndeclaredClassMethod - Class is missing from php-stubs/wp-cli-stubs 🤷
1869 1911 $progress->tick();
1870 1912 }
1871 1913
1914 + // @phan-suppress-next-line PhanUndeclaredClassMethod - Class is missing from php-stubs/wp-cli-stubs 🤷
1872 1915 $progress->finish();
1873 1916
1874 1917 if ( 'all' === $service ) {
1875 1918 WP_CLI::success( __( 'All Jetpack Social connections were successfully disconnected.', 'jetpack' ) );
@@ -1874,9 +1917,9 @@
1874 1917 if ( 'all' === $service ) {
1875 1918 WP_CLI::success( __( 'All Jetpack Social connections were successfully disconnected.', 'jetpack' ) );
1876 1919 } else {
1877 1920 /* translators: %s is a lowercase string for a social network. */
1878 - WP_CLI::success( __( 'All Jetpack Social connections to %s were successfully disconnected.', 'jetpack' ), $service );
1921 + WP_CLI::success( sprintf( __( 'All Jetpack Social connections to %s were successfully disconnected.', 'jetpack' ), $service ) );
1879 1922 }
1880 1923 }
1881 1924 } elseif ( false !== $publicize->disconnect( false, $identifier ) ) {
1882 1925 /* translators: %d is a numeric ID. Example: 1234. */
@@ -1911,9 +1954,10 @@
1911 1954 array(
1912 1955 'success' => false,
1913 1956 'error_code' => $error->get_error_code(),
1914 1957 'error_message' => $error->get_error_message(),
1915 - )
1958 + ),
1959 + JSON_UNESCAPED_SLASHES
1916 1960 )
1917 1961 );
1918 1962 exit( 1 );
1919 1963 }
@@ -1966,19 +2010,17 @@
1966 2010 * @param array $args Positional parameters. Only one is used, that corresponds to the block title.
1967 2011 * @param array $assoc_args Associative parameters defined in the scaffold() method.
1968 2012 */
1969 2013 public function block( $args, $assoc_args ) {
1970 - if ( isset( $args[1] ) ) {
1971 - $title = ucwords( $args[1] );
1972 - } else {
2014 + if ( ! isset( $args[1] ) ) {
1973 2015 WP_CLI::error( esc_html__( 'The title parameter is required.', 'jetpack' ) . ' 👻' );
1974 2016 exit( 1 );
1975 2017 }
1976 2018
1977 - $slug = isset( $assoc_args['slug'] )
1978 - ? $assoc_args['slug']
1979 - : sanitize_title( $title );
2019 + $title = ucwords( $args[1] );
1980 2020
2021 + $slug = $assoc_args['slug'] ?? sanitize_title( $title );
2022 +
1981 2023 $next_version = "\x24\x24next-version$$"; // Escapes to hide the string from tools/replace-next-version-tag.sh
1982 2024
1983 2025 $variation_options = array( 'production', 'experimental', 'beta' );
1984 2026 $variation = ( isset( $assoc_args['variation'] ) && in_array( $assoc_args['variation'], $variation_options, true ) )
@@ -2021,14 +2063,14 @@
2021 2063 "$path/block.json" => self::render_block_file(
2022 2064 'block-block-json',
2023 2065 array(
2024 2066 'slug' => $slug,
2025 - 'title' => wp_json_encode( $title, JSON_UNESCAPED_UNICODE ),
2067 + 'title' => wp_json_encode( $title, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ),
2026 2068 'description' => isset( $assoc_args['description'] )
2027 - ? wp_json_encode( $assoc_args['description'], JSON_UNESCAPED_UNICODE )
2028 - : wp_json_encode( $title, JSON_UNESCAPED_UNICODE ),
2069 + ? wp_json_encode( $assoc_args['description'], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE )
2070 + : wp_json_encode( $title, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ),
2029 2071 'nextVersion' => $next_version,
2030 - 'keywords' => wp_json_encode( $keywords, JSON_UNESCAPED_UNICODE ),
2072 + 'keywords' => wp_json_encode( $keywords, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ),
2031 2073 )
2032 2074 ),
2033 2075 "$path/$slug.php" => self::render_block_file(
2034 2076 'block-register-php',
@@ -2079,9 +2121,9 @@
2079 2121 $new_block_list = json_decode( $block_list );
2080 2122 $new_block_list->{ $variation }[] = $slug;
2081 2123
2082 2124 // Format the JSON to match our coding standards.
2083 - $new_block_list_formatted = wp_json_encode( $new_block_list, JSON_PRETTY_PRINT ) . "\n";
2125 + $new_block_list_formatted = wp_json_encode( $new_block_list, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT ) . "\n";
2084 2126 $new_block_list_formatted = preg_replace_callback(
2085 2127 // Find all occurrences of multiples of 4 spaces a the start of the line.
2086 2128 '/^((?: )+)/m',
2087 2129 function ( $matches ) {