PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 7.9
Jetpack – WP Security, Backup, Speed, & Growth v7.9
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 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
← All changes | class.jetpack-cli.php +228 -385 13.2.47.9 View file →
@@ -1,60 +1,23 @@
1 -<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 -/**
3 - * WP-CLI command class.
4 - *
5 - * @package automattic/jetpack
6 - */
1 +<?php
7 2
3 +WP_CLI::add_command( 'jetpack', 'Jetpack_CLI' );
4 +
8 5 use Automattic\Jetpack\Connection\Client;
9 6 use Automattic\Jetpack\Connection\Manager as Connection_Manager;
10 -use Automattic\Jetpack\Connection\Tokens;
11 -use Automattic\Jetpack\Identity_Crisis;
12 -use Automattic\Jetpack\IP\Utils as IP_Utils;
13 -use Automattic\Jetpack\Status;
14 7 use Automattic\Jetpack\Sync\Actions;
15 8 use Automattic\Jetpack\Sync\Listener;
16 -use Automattic\Jetpack\Sync\Modules;
17 9 use Automattic\Jetpack\Sync\Queue;
18 10 use Automattic\Jetpack\Sync\Settings;
19 -use Automattic\Jetpack\Waf\Brute_Force_Protection\Brute_Force_Protection_Shared_Functions;
20 11
21 -if ( ! class_exists( 'WP_CLI_Command' ) ) {
22 - return;
23 -}
24 -
25 -WP_CLI::add_command( 'jetpack', 'Jetpack_CLI' );
26 -
27 12 /**
28 13 * Control your local Jetpack installation.
29 14 */
30 15 class Jetpack_CLI extends WP_CLI_Command {
31 - /**
32 - * Console escape code for green.
33 - *
34 - * @var string
35 - */
36 - public $green_open = "\033[32m";
37 -
38 - /**
39 - * Console escape code for red.
40 - *
41 - * @var string
42 - */
43 - public $red_open = "\033[31m";
44 -
45 - /**
46 - * Console escape code for yellow.
47 - *
48 - * @var string
49 - */
16 + // Aesthetics.
17 + public $green_open = "\033[32m";
18 + public $red_open = "\033[31m";
50 19 public $yellow_open = "\033[33m";
51 -
52 - /**
53 - * Console escape code to reset coloring.
54 - *
55 - * @var string
56 - */
57 20 public $color_close = "\033[0m";
58 21
59 22 /**
60 23 * Get Jetpack Details
@@ -68,13 +31,11 @@
68 31 * ## EXAMPLES
69 32 *
70 33 * wp jetpack status
71 34 * wp jetpack status full
72 - *
73 - * @param array $args Positional args.
74 35 */
75 - public function status( $args ) {
76 - require_once JETPACK__PLUGIN_DIR . '_inc/lib/debugger.php';
36 + public function status( $args, $assoc_args ) {
37 + jetpack_require_lib( 'debugger' );
77 38
78 39 /* translators: %s is the site URL */
79 40 WP_CLI::line( sprintf( __( 'Checking status for %s', 'jetpack' ), esc_url( get_home_url() ) ) );
80 41
@@ -93,15 +54,15 @@
93 54 WP_CLI::success( __( 'Jetpack is currently connected to WordPress.com', 'jetpack' ) );
94 55 } else {
95 56 $error = array();
96 57 foreach ( $cxntests->list_fails() as $fail ) {
97 - $error[] = $fail['name'] . ( empty( $fail['message'] ) ? '' : ': ' . $fail['message'] );
58 + $error[] = $fail['name'] . ': ' . $fail['message'];
98 59 }
99 60 WP_CLI::error_multi_line( $error );
100 61
101 62 $cxntests->output_results_for_cli();
102 63
103 - WP_CLI::error( __( 'One or more tests did not pass. Please investigate!', 'jetpack' ) ); // Exit CLI.
64 + WP_CLI::error( __( 'Jetpack connection is broken.', 'jetpack' ) ); // Exit CLI.
104 65 }
105 66
106 67 /* translators: %s is current version of Jetpack, for example 7.3 */
107 68 WP_CLI::line( sprintf( __( 'The Jetpack Version is %s', 'jetpack' ), JETPACK__VERSION ) );
@@ -114,41 +75,41 @@
114 75 * Are they asking for all data?
115 76 *
116 77 * Loop through heartbeat data and organize by priority.
117 78 */
118 - $all_data = ( isset( $args[0] ) && 'full' === $args[0] ) ? 'full' : false;
79 + $all_data = ( isset( $args[0] ) && 'full' == $args[0] ) ? 'full' : false;
119 80 if ( $all_data ) {
120 - // Heartbeat data.
81 + // Heartbeat data
121 82 WP_CLI::line( "\n" . __( 'Additional data: ', 'jetpack' ) );
122 83
123 84 // Get the filtered heartbeat data.
124 - // Filtered so we can color/list by severity.
85 + // Filtered so we can color/list by severity
125 86 $stats = Jetpack::jetpack_check_heartbeat_data();
126 87
127 - // Display red flags first.
88 + // Display red flags first
128 89 foreach ( $stats['bad'] as $stat => $value ) {
129 - WP_CLI::line( sprintf( "$this->red_open%-'.16s %s $this->color_close", $stat, $value ) );
90 + printf( "$this->red_open%-'.16s %s $this->color_close\n", $stat, $value );
130 91 }
131 92
132 - // Display caution warnings next.
93 + // Display caution warnings next
133 94 foreach ( $stats['caution'] as $stat => $value ) {
134 - WP_CLI::line( sprintf( "$this->yellow_open%-'.16s %s $this->color_close", $stat, $value ) );
95 + printf( "$this->yellow_open%-'.16s %s $this->color_close\n", $stat, $value );
135 96 }
136 97
137 98 // The rest of the results are good!
138 99 foreach ( $stats['good'] as $stat => $value ) {
139 100
140 - // Modules should get special spacing for aestetics.
101 + // Modules should get special spacing for aestetics
141 102 if ( strpos( $stat, 'odule-' ) ) {
142 - WP_CLI::line( sprintf( "%-'.30s %s", $stat, $value ) );
143 - usleep( 4000 ); // For dramatic effect lolz.
103 + printf( "%-'.30s %s\n", $stat, $value );
104 + usleep( 4000 ); // For dramatic effect lolz
144 105 continue;
145 106 }
146 - WP_CLI::line( sprintf( "%-'.16s %s", $stat, $value ) );
147 - usleep( 4000 ); // For dramatic effect lolz.
107 + printf( "%-'.16s %s\n", $stat, $value );
108 + usleep( 4000 ); // For dramatic effect lolz
148 109 }
149 110 } else {
150 - // Just the basics.
111 + // Just the basics
151 112 WP_CLI::line( "\n" . _x( "View full status with 'wp jetpack status full'", '"wp jetpack status full" is a command - do not translate', 'jetpack' ) );
152 113 }
153 114 }
154 115
@@ -162,14 +123,14 @@
162 123 * wp jetpack test-connection
163 124 *
164 125 * @subcommand test-connection
165 126 */
166 - public function test_connection() {
127 + public function test_connection( $args, $assoc_args ) {
167 128
168 129 /* translators: %s is the site URL */
169 130 WP_CLI::line( sprintf( __( 'Testing connection for %s', 'jetpack' ), esc_url( get_site_url() ) ) );
170 131
171 - if ( ! Jetpack::is_connection_ready() ) {
132 + if ( ! Jetpack::is_active() ) {
172 133 WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
173 134 }
174 135
175 136 $response = Client::wpcom_json_api_request_as_blog(
@@ -206,38 +167,34 @@
206 167 * blog: Disconnect the entire blog.
207 168 *
208 169 * user <user_identifier>: Disconnect a specific user from WordPress.com.
209 170 *
210 - * [--force]
211 - * If the user ID provided is the connection owner, it will only be disconnected if --force is passed
171 + * Please note, the primary account that the blog is connected
172 + * to WordPress.com with cannot be disconnected without
173 + * disconnecting the entire blog.
212 174 *
213 175 * ## EXAMPLES
214 176 *
215 177 * wp jetpack disconnect blog
216 178 * wp jetpack disconnect user 13
217 - * wp jetpack disconnect user 1 --force
218 179 * wp jetpack disconnect user username
219 180 * wp jetpack disconnect user email@domain.com
220 181 *
221 - * @synopsis <blog|user> [<user_identifier>] [--force]
222 - *
223 - * @param array $args Positional args.
224 - * @param array $assoc_args Named args.
182 + * @synopsis <blog|user> [<user_identifier>]
225 183 */
226 184 public function disconnect( $args, $assoc_args ) {
227 - $user = null;
228 - if ( ! Jetpack::is_connection_ready() ) {
185 + if ( ! Jetpack::is_active() ) {
229 186 WP_CLI::success( __( 'The site is not currently connected, so nothing to do!', 'jetpack' ) );
230 187 return;
231 188 }
232 189
233 190 $action = isset( $args[0] ) ? $args[0] : 'prompt';
234 - if ( ! in_array( $action, array( 'blog', 'user', 'prompt' ), true ) ) {
191 + if ( ! in_array( $action, array( 'blog', 'user', 'prompt' ) ) ) {
235 192 /* translators: %s is a command like "prompt" */
236 193 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
237 194 }
238 195
239 - if ( in_array( $action, array( 'user' ), true ) ) {
196 + if ( in_array( $action, array( 'user' ) ) ) {
240 197 if ( isset( $args[1] ) ) {
241 198 $user_id = $args[1];
242 199 if ( ctype_digit( $user_id ) ) {
243 200 $field = 'id';
@@ -248,10 +205,9 @@
248 205 } else {
249 206 $field = 'login';
250 207 $user_id = sanitize_user( $user_id, true );
251 208 }
252 - $user = get_user_by( $field, $user_id );
253 - if ( ! $user ) {
209 + if ( ! $user = get_user_by( $field, $user_id ) ) {
254 210 WP_CLI::error( __( 'Please specify a valid user.', 'jetpack' ) );
255 211 }
256 212 } else {
257 213 WP_CLI::error( __( 'Please specify a user by either ID, username, or email.', 'jetpack' ) );
@@ -257,14 +213,12 @@
257 213 WP_CLI::error( __( 'Please specify a user by either ID, username, or email.', 'jetpack' ) );
258 214 }
259 215 }
260 216
261 - $force_user_disconnect = ! empty( $assoc_args['force'] );
262 -
263 217 switch ( $action ) {
264 218 case 'blog':
265 219 Jetpack::log( 'disconnect' );
266 - ( new Connection_Manager( 'jetpack' ) )->disconnect_site();
220 + Jetpack::disconnect();
267 221 WP_CLI::success(
268 222 sprintf(
269 223 /* translators: %s is the site URL */
270 224 __( 'Jetpack has been successfully disconnected for %s.', 'jetpack' ),
@@ -272,25 +226,14 @@
272 226 )
273 227 );
274 228 break;
275 229 case 'user':
276 - $connection_manager = new Connection_Manager( 'jetpack' );
277 - $disconnected = $connection_manager->disconnect_user( $user->ID, $force_user_disconnect );
278 - if ( $disconnected ) {
230 + if ( Connection_Manager::disconnect_user( $user->ID ) ) {
279 231 Jetpack::log( 'unlink', $user->ID );
280 232 WP_CLI::success( __( 'User has been successfully disconnected.', 'jetpack' ) );
281 233 } else {
282 - if ( ! $connection_manager->is_user_connected( $user->ID ) ) {
283 - /* translators: %s is a username */
284 - $error_message = sprintf( __( 'User %s could not be disconnected because it is not connected!', 'jetpack' ), "{$user->data->user_login} <{$user->data->user_email}>" );
285 - } elseif ( ! $force_user_disconnect && $connection_manager->is_connection_owner( $user->ID ) ) {
286 - /* translators: %s is a username */
287 - $error_message = sprintf( __( 'User %s could not be disconnected because it is the connection owner! If you want to disconnect in anyway, use the --force parameter.', 'jetpack' ), "{$user->data->user_login} <{$user->data->user_email}>" );
288 - } else {
289 - /* translators: %s is a username */
290 - $error_message = sprintf( __( 'User %s could not be disconnected.', 'jetpack' ), "{$user->data->user_login} <{$user->data->user_email}>" );
291 - }
292 - WP_CLI::error( $error_message );
234 + /* translators: %s is a username */
235 + WP_CLI::error( sprintf( __( "User %s could not be disconnected. Are you sure they're connected currently?", 'jetpack' ), "{$user->login} <{$user->email}>" ) );
293 236 }
294 237 break;
295 238 case 'prompt':
296 239 WP_CLI::error( __( 'Please specify if you would like to disconnect a blog or user.', 'jetpack' ) );
@@ -318,11 +261,8 @@
318 261 * wp jetpack reset modules
319 262 * wp jetpack reset sync-checksum --dry-run --offset=0
320 263 *
321 264 * @synopsis <modules|options|sync-checksum> [--dry-run] [--offset=<offset>]
322 - *
323 - * @param array $args Positional args.
324 - * @param array $assoc_args Named args.
325 265 */
326 266 public function reset( $args, $assoc_args ) {
327 267 $action = isset( $args[0] ) ? $args[0] : 'prompt';
328 268 if ( ! in_array( $action, array( 'options', 'modules', 'sync-checksum' ), true ) ) {
@@ -345,9 +285,9 @@
345 285
346 286 switch ( $action ) {
347 287 case 'options':
348 288 $options_to_reset = Jetpack_Options::get_options_for_reset();
349 - // Reset the Jetpack options.
289 + // Reset the Jetpack options
350 290 WP_CLI::line(
351 291 sprintf(
352 292 /* translators: %s is the site URL */
353 293 __( "Resetting Jetpack Options for %s...\n", 'jetpack' ),
@@ -353,9 +293,9 @@
353 293 __( "Resetting Jetpack Options for %s...\n", 'jetpack' ),
354 294 esc_url( get_site_url() )
355 295 )
356 296 );
357 - sleep( 1 ); // Take a breath.
297 + sleep( 1 ); // Take a breath
358 298 foreach ( $options_to_reset['jp_options'] as $option_to_reset ) {
359 299 if ( ! $is_dry_run ) {
360 300 Jetpack_Options::delete_option( $option_to_reset );
361 301 usleep( 100000 );
@@ -364,11 +304,11 @@
364 304 /* translators: This is the result of an action. The option named %s was reset */
365 305 WP_CLI::success( sprintf( __( '%s option reset', 'jetpack' ), $option_to_reset ) );
366 306 }
367 307
368 - // Reset the WP options.
308 + // Reset the WP options
369 309 WP_CLI::line( __( "Resetting the jetpack options stored in wp_options...\n", 'jetpack' ) );
370 - usleep( 500000 ); // Take a breath.
310 + usleep( 500000 ); // Take a breath
371 311 foreach ( $options_to_reset['wp_options'] as $option_to_reset ) {
372 312 if ( ! $is_dry_run ) {
373 313 delete_option( $option_to_reset );
374 314 usleep( 100000 );
@@ -376,11 +316,11 @@
376 316 /* translators: This is the result of an action. The option named %s was reset */
377 317 WP_CLI::success( sprintf( __( '%s option reset', 'jetpack' ), $option_to_reset ) );
378 318 }
379 319
380 - // Reset to default modules.
320 + // Reset to default modules
381 321 WP_CLI::line( __( "Resetting default modules...\n", 'jetpack' ) );
382 - usleep( 500000 ); // Take a breath.
322 + usleep( 500000 ); // Take a breath
383 323 $default_modules = Jetpack::get_default_modules();
384 324 if ( ! $is_dry_run ) {
385 325 Jetpack::update_active_modules( $default_modules );
386 326 }
@@ -429,9 +369,9 @@
429 369 $option,
430 370 "{$site->domain}{$site->path}"
431 371 )
432 372 );
433 - ++$count_fixes;
373 + $count_fixes++;
434 374 if ( ! $is_dry_run ) {
435 375 /*
436 376 * We could be deleting a lot of options rows at the same time.
437 377 * Allow some time for replication to catch up.
@@ -495,8 +435,9 @@
495 435 "SELECT COUNT(*) FROM $wpdb->options WHERE option_name = %s",
496 436 $option
497 437 )
498 438 );
439 +
499 440 }
500 441
501 442 /**
502 443 * Manage Jetpack Modules
@@ -538,15 +479,11 @@
538 479 * wp jetpack module deactivate stats
539 480 * wp jetpack module toggle stats
540 481 * wp jetpack module activate all
541 482 * wp jetpack module deactivate all
542 - *
543 - * @param array $args Positional args.
544 - * @param array $assoc_args Named args.
545 483 */
546 484 public function module( $args, $assoc_args ) {
547 - $module_slug = null;
548 - $action = isset( $args[0] ) ? $args[0] : 'list';
485 + $action = isset( $args[0] ) ? $args[0] : 'list';
549 486
550 487 if ( isset( $args[1] ) ) {
551 488 $module_slug = $args[1];
552 489 if ( 'all' !== $module_slug && ! Jetpack::is_module( $module_slug ) ) {
@@ -623,122 +560,120 @@
623 560 * Manage Protect Settings
624 561 *
625 562 * ## OPTIONS
626 563 *
627 - * allow: Add an IP address to an always allow list. You can also read or clear the allow list.
564 + * whitelist: Whitelist an IP address. You can also read or clear the whitelist.
628 565 *
629 566 *
630 567 * ## EXAMPLES
631 568 *
632 - * wp jetpack protect allow <ip address>
633 - * wp jetpack protect allow list
634 - * wp jetpack protect allow clear
569 + * wp jetpack protect whitelist <ip address>
570 + * wp jetpack protect whitelist list
571 + * wp jetpack protect whitelist clear
635 572 *
636 - * @synopsis <allow> [<ip|ip_low-ip_high|list|clear>]
637 - *
638 - * @param array $args Positional args.
573 + * @synopsis <whitelist> [<ip|ip_low-ip_high|list|clear>]
639 574 */
640 - public function protect( $args ) {
575 + public function protect( $args, $assoc_args ) {
641 576 $action = isset( $args[0] ) ? $args[0] : 'prompt';
642 - if ( ! in_array( $action, array( 'whitelist', 'allow' ), true ) ) { // Still allow "whitelist" for legacy support.
577 + if ( ! in_array( $action, array( 'whitelist' ) ) ) {
643 578 /* translators: %s is a command like "prompt" */
644 579 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
645 580 }
646 - // Check if module is active.
581 + // Check if module is active
647 582 if ( ! Jetpack::is_module_active( __FUNCTION__ ) ) {
648 583 /* translators: %s is a module name */
649 584 WP_CLI::error( sprintf( _x( '%1$s is not active. You can activate it with "wp jetpack module activate %2$s"', '"wp jetpack module activate" is a command - do not translate', 'jetpack' ), __FUNCTION__, __FUNCTION__ ) );
650 585 }
651 - if ( in_array( $action, array( 'allow', 'whitelist' ), true ) ) {
586 + if ( in_array( $action, array( 'whitelist' ) ) ) {
652 587 if ( isset( $args[1] ) ) {
653 - $action = 'allow';
588 + $action = 'whitelist';
654 589 } else {
655 590 $action = 'prompt';
656 591 }
657 592 }
658 593 switch ( $action ) {
659 - case 'allow':
660 - $allow = array();
661 - $new_ip = $args[1];
662 - $current_allow = get_site_option( 'jetpack_protect_whitelist', array() ); // @todo Update the option name.
594 + case 'whitelist':
595 + $whitelist = array();
596 + $new_ip = $args[1];
597 + $current_whitelist = get_site_option( 'jetpack_protect_whitelist', array() );
663 598
664 - // Build array of IPs that are already on the allowed list.
665 - // Re-build manually instead of using jetpack_protect_format_allow_list() so we can easily get
666 - // low & high range params for IP_Utils::ip_address_is_in_range().
667 - foreach ( $current_allow as $allowed ) {
599 + // Build array of IPs that are already whitelisted.
600 + // Re-build manually instead of using jetpack_protect_format_whitelist() so we can easily get
601 + // low & high range params for jetpack_protect_ip_address_is_in_range();
602 + foreach ( $current_whitelist as $whitelisted ) {
668 603
669 - // IP ranges.
670 - if ( $allowed->range ) {
604 + // IP ranges
605 + if ( $whitelisted->range ) {
671 606
672 - // Is it already on the allowed list?
673 - if ( IP_Utils::ip_address_is_in_range( $new_ip, $allowed->range_low, $allowed->range_high ) ) {
607 + // Is it already whitelisted?
608 + if ( jetpack_protect_ip_address_is_in_range( $new_ip, $whitelisted->range_low, $whitelisted->range_high ) ) {
674 609 /* translators: %s is an IP address */
675 - WP_CLI::error( sprintf( __( '%s is already on the always allow list.', 'jetpack' ), $new_ip ) );
610 + WP_CLI::error( sprintf( __( '%s has already been whitelisted', 'jetpack' ), $new_ip ) );
676 611 break;
677 612 }
678 - $allow[] = $allowed->range_low . ' - ' . $allowed->range_high;
613 + $whitelist[] = $whitelisted->range_low . ' - ' . $whitelisted->range_high;
679 614
680 - } else { // Individual IPs.
615 + } else { // Individual IPs
681 616
682 - // Check if the IP is already on the allow list (single IP only).
683 - if ( $new_ip === $allowed->ip_address ) {
617 + // Check if the IP is already whitelisted (single IP only)
618 + if ( $new_ip == $whitelisted->ip_address ) {
684 619 /* translators: %s is an IP address */
685 - WP_CLI::error( sprintf( __( '%s is already on the always allow list.', 'jetpack' ), $new_ip ) );
620 + WP_CLI::error( sprintf( __( '%s has already been whitelisted', 'jetpack' ), $new_ip ) );
686 621 break;
687 622 }
688 - $allow[] = $allowed->ip_address;
623 + $whitelist[] = $whitelisted->ip_address;
689 624
690 625 }
691 626 }
692 627
693 628 /*
694 - * List the allowed IPs.
695 - * Done here because it's easier to read the $allow array after it's been rebuilt.
629 + * List the whitelist
630 + * Done here because it's easier to read the $whitelist array after it's been rebuilt
696 631 */
697 - if ( isset( $args[1] ) && 'list' === $args[1] ) {
698 - if ( ! empty( $allow ) ) {
699 - WP_CLI::success( __( 'Here are your always allowed IPs:', 'jetpack' ) );
700 - foreach ( $allow as $ip ) {
632 + if ( isset( $args[1] ) && 'list' == $args[1] ) {
633 + if ( ! empty( $whitelist ) ) {
634 + WP_CLI::success( __( 'Here are your whitelisted IPs:', 'jetpack' ) );
635 + foreach ( $whitelist as $ip ) {
701 636 WP_CLI::line( "\t" . str_pad( $ip, 24 ) );
702 637 }
703 638 } else {
704 - WP_CLI::line( __( 'Always allow list is empty.', 'jetpack' ) );
639 + WP_CLI::line( __( 'Whitelist is empty.', 'jetpack' ) );
705 640 }
706 641 break;
707 642 }
708 643
709 644 /*
710 - * Clear the always allow list.
645 + * Clear the whitelist
711 646 */
712 - if ( isset( $args[1] ) && 'clear' === $args[1] ) {
713 - if ( ! empty( $allow ) ) {
714 - $allow = array();
715 - Brute_Force_Protection_Shared_Functions::save_allow_list( $allow ); // @todo Need to update function name in the Protect module.
716 - WP_CLI::success( __( 'Cleared all IPs from the always allow list.', 'jetpack' ) );
647 + if ( isset( $args[1] ) && 'clear' == $args[1] ) {
648 + if ( ! empty( $whitelist ) ) {
649 + $whitelist = array();
650 + jetpack_protect_save_whitelist( $whitelist );
651 + WP_CLI::success( __( 'Cleared all whitelisted IPs', 'jetpack' ) );
717 652 } else {
718 - WP_CLI::line( __( 'Always allow list is empty.', 'jetpack' ) );
653 + WP_CLI::line( __( 'Whitelist is empty.', 'jetpack' ) );
719 654 }
720 655 break;
721 656 }
722 657
723 - // Append new IP to allow array.
724 - array_push( $allow, $new_ip );
658 + // Append new IP to whitelist array
659 + array_push( $whitelist, $new_ip );
725 660
726 - // Save allow list if there are no errors.
727 - $result = Brute_Force_Protection_Shared_Functions::save_allow_list( $allow ); // @todo Need to update function name in the Protect module.
661 + // Save whitelist if there are no errors
662 + $result = jetpack_protect_save_whitelist( $whitelist );
728 663 if ( is_wp_error( $result ) ) {
729 664 WP_CLI::error( $result );
730 665 }
731 666
732 667 /* translators: %s is an IP address */
733 - WP_CLI::success( sprintf( __( '%s has been added to the always allowed list.', 'jetpack' ), $new_ip ) );
668 + WP_CLI::success( sprintf( __( '%s has been whitelisted.', 'jetpack' ), $new_ip ) );
734 669 break;
735 670 case 'prompt':
736 671 WP_CLI::error(
737 672 __( 'No command found.', 'jetpack' ) . "\n" .
738 - __( 'Please enter the IP address you want to always allow.', 'jetpack' ) . "\n" .
739 - _x( 'You can save a range of IPs {low_range}-{high_range}. No spaces allowed. (example: 1.1.1.1-2.2.2.2)', 'Instructions on how to add IP ranges - low_range/high_range should be translated.', 'jetpack' ) . "\n" .
740 - _x( "You can also 'list' or 'clear' the always allowed list.", "'list' and 'clear' are commands and should not be translated", 'jetpack' ) . "\n"
673 + __( 'Please enter the IP address you want to whitelist.', 'jetpack' ) . "\n" .
674 + _x( 'You can save a range of IPs {low_range}-{high_range}. No spaces allowed. (example: 1.1.1.1-2.2.2.2)', 'Instructions on how to whitelist IP ranges - low_range/high_range should be translated.', 'jetpack' ) . "\n" .
675 + _x( "You can also 'list' or 'clear' the whitelist.", "'list' and 'clear' are commands and should not be translated", 'jetpack' ) . "\n"
741 676 );
742 677 break;
743 678 }
744 679 }
@@ -762,29 +697,27 @@
762 697 * wp jetpack options delete <option_name>
763 698 * wp jetpack options update <option_name> [<option_value>]
764 699 *
765 700 * @synopsis <list|get|delete|update> [<option_name>] [<option_value>]
766 - *
767 - * @param array $args Positional args.
768 701 */
769 - public function options( $args ) {
702 + public function options( $args, $assoc_args ) {
770 703 $action = isset( $args[0] ) ? $args[0] : 'list';
771 704 $safe_to_modify = Jetpack_Options::get_options_for_reset();
772 705
773 706 // Is the option flagged as unsafe?
774 - $flagged = ! in_array( $args[1], $safe_to_modify, true );
707 + $flagged = ! in_array( $args[1], $safe_to_modify );
775 708
776 - if ( ! in_array( $action, array( 'list', 'get', 'delete', 'update' ), true ) ) {
709 + if ( ! in_array( $action, array( 'list', 'get', 'delete', 'update' ) ) ) {
777 710 /* translators: %s is a command like "prompt" */
778 711 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
779 712 }
780 713
781 714 if ( isset( $args[0] ) ) {
782 - if ( 'get' === $args[0] && isset( $args[1] ) ) {
715 + if ( 'get' == $args[0] && isset( $args[1] ) ) {
783 716 $action = 'get';
784 - } elseif ( 'delete' === $args[0] && isset( $args[1] ) ) {
717 + } elseif ( 'delete' == $args[0] && isset( $args[1] ) ) {
785 718 $action = 'delete';
786 - } elseif ( 'update' === $args[0] && isset( $args[1] ) ) {
719 + } elseif ( 'update' == $args[0] && isset( $args[1] ) ) {
787 720 $action = 'update';
788 721 } else {
789 722 $action = 'list';
790 723 }
@@ -789,18 +722,17 @@
789 722 $action = 'list';
790 723 }
791 724 }
792 725
793 - // Bail if the option isn't found.
726 + // Bail if the option isn't found
794 727 $option = isset( $args[1] ) ? Jetpack_Options::get_option( $args[1] ) : false;
795 728 if ( isset( $args[1] ) && ! $option && 'update' !== $args[0] ) {
796 - WP_CLI::error( __( 'Option not found or is empty. Use "list" to list option names', 'jetpack' ) );
729 + WP_CLI::error( __( 'Option not found or is empty. Use "list" to list option names', 'jetpack' ) );
797 730 }
798 731
799 - // Let's print_r the option if it's an array.
800 - // Used in the 'get' and 'list' actions.
801 - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
802 - $option = is_array( $option ) ? print_r( $option, true ) : $option;
732 + // Let's print_r the option if it's an array
733 + // Used in the 'get' and 'list' actions
734 + $option = is_array( $option ) ? print_r( $option ) : $option;
803 735
804 736 switch ( $action ) {
805 737 case 'get':
806 738 WP_CLI::success( "\t" . $option );
@@ -830,14 +762,14 @@
830 762 $options_non_compact = Jetpack_Options::get_option_names( 'non_compact' );
831 763 $options_private = Jetpack_Options::get_option_names( 'private' );
832 764 $options = array_merge( $options_compact, $options_non_compact, $options_private );
833 765
834 - // Table headers.
766 + // Table headers
835 767 WP_CLI::line( "\t" . str_pad( __( 'Option', 'jetpack' ), 30 ) . __( 'Value', 'jetpack' ) );
836 768
837 - // List out the options and their values.
838 - // Tell them if the value is empty or not.
839 - // Tell them if it's an array.
769 + // List out the options and their values
770 + // Tell them if the value is empty or not
771 + // Tell them if it's an array
840 772 foreach ( $options as $option ) {
841 773 $value = Jetpack_Options::get_option( $option );
842 774 if ( ! $value ) {
843 775 WP_CLI::line( "\t" . str_pad( $option, 30 ) . 'Empty' );
@@ -856,9 +788,9 @@
856 788 WP_CLI::success(
857 789 _x( "Above are your options. You may 'get', 'delete', and 'update' them.", "'get', 'delete', and 'update' are commands - do not translate.", 'jetpack' ) . "\n" .
858 790 str_pad( 'wp jetpack options get', 26 ) . $option_text . "\n" .
859 791 str_pad( 'wp jetpack options delete', 26 ) . $option_text . "\n" .
860 - str_pad( 'wp jetpack options update', 26 ) . "$option_text $value_text\n" .
792 + str_pad( 'wp jetpack options update', 26 ) . "$option_text $value_text" . "\n" .
861 793 _x( "Type 'wp jetpack options' for more info.", "'wp jetpack options' is a command - do not translate.", 'jetpack' ) . "\n"
862 794 );
863 795 break;
864 796 }
@@ -886,11 +818,8 @@
886 818 * wp jetpack sync reset
887 819 * wp jetpack sync reset --queue=full or regular
888 820 *
889 821 * @synopsis <status|start> [--<field>=<value>]
890 - *
891 - * @param array $args Positional args.
892 - * @param array $assoc_args Named args.
893 822 */
894 823 public function sync( $args, $assoc_args ) {
895 824
896 825 $action = isset( $args[0] ) ? $args[0] : 'status';
@@ -901,9 +830,9 @@
901 830 $collection = array();
902 831 foreach ( $status as $key => $item ) {
903 832 $collection[] = array(
904 833 'option' => $key,
905 - 'value' => is_scalar( $item ) ? $item : wp_json_encode( $item ),
834 + 'value' => is_scalar( $item ) ? $item : json_encode( $item ),
906 835 );
907 836 }
908 837 WP_CLI::log( __( 'Sync Status:', 'jetpack' ) );
909 838 WP_CLI\Utils\format_items( 'table', $collection, array( 'option', 'value' ) );
@@ -909,17 +838,16 @@
909 838 WP_CLI\Utils\format_items( 'table', $collection, array( 'option', 'value' ) );
910 839 break;
911 840 case 'settings':
912 841 WP_CLI::log( __( 'Sync Settings:', 'jetpack' ) );
913 - $settings = array();
914 842 foreach ( Settings::get_settings() as $setting => $item ) {
915 843 $settings[] = array(
916 844 'setting' => $setting,
917 - 'value' => is_scalar( $item ) ? $item : wp_json_encode( $item ),
845 + 'value' => is_scalar( $item ) ? $item : json_encode( $item ),
918 846 );
919 847 }
920 848 WP_CLI\Utils\format_items( 'table', $settings, array( 'setting', 'value' ) );
921 - break;
849 +
922 850 case 'disable':
923 851 // Don't set it via the Settings since that also resets the queues.
924 852 update_option( 'jetpack_sync_settings_disable', 1 );
925 853 /* translators: %s is the site URL */
@@ -965,35 +893,29 @@
965 893
966 894 break;
967 895 case 'start':
968 896 if ( ! Actions::sync_allowed() ) {
969 - if ( Settings::get_setting( 'disable' ) ) {
897 + if ( ! Settings::get_setting( 'disable' ) ) {
970 898 WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. It is currently disabled. Run `wp jetpack sync enable` to enable it.', 'jetpack' ) );
971 899 return;
972 900 }
973 - $connection = new Connection_Manager();
974 - if ( ! $connection->is_connected() ) {
975 - if ( ! doing_action( 'jetpack_site_registered' ) ) {
976 - WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. Jetpack is not connected.', 'jetpack' ) );
977 - return;
978 - }
901 + if ( doing_action( 'jetpack_user_authorized' ) || Jetpack::is_active() ) {
902 + WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. Jetpack is not connected.', 'jetpack' ) );
903 + return;
979 904 }
980 -
981 - $status = new Status();
982 -
983 - if ( $status->is_offline_mode() ) {
984 - WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in offline mode.', 'jetpack' ) );
905 + if ( Jetpack::is_development_mode() ) {
906 + WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in development mode.', 'jetpack' ) );
985 907 return;
986 908 }
987 - if ( $status->is_staging_site() ) {
909 + if ( Jetpack::is_staging_site() ) {
988 910 WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in staging mode.', 'jetpack' ) );
989 911 return;
990 912 }
991 913 }
992 - // Get the original settings so that we can restore them later.
914 + // Get the original settings so that we can restore them later
993 915 $original_settings = Settings::get_settings();
994 916
995 - // Initialize sync settigns so we can sync as quickly as possible.
917 + // Initialize sync settigns so we can sync as quickly as possible
996 918 $sync_settings = wp_parse_args(
997 919 array_intersect_key( $assoc_args, Settings::$valid_settings ),
998 920 array(
999 921 'sync_wait_time' => 0,
@@ -999,19 +921,18 @@
999 921 'sync_wait_time' => 0,
1000 922 'enqueue_wait_time' => 0,
1001 923 'queue_max_writes_sec' => 10000,
1002 924 'max_queue_size_full_sync' => 100000,
1003 - 'full_sync_send_duration' => HOUR_IN_SECONDS,
1004 925 )
1005 926 );
1006 927 Settings::update_settings( $sync_settings );
1007 928
1008 - // Convert comma-delimited string of modules to an array.
929 + // Convert comma-delimited string of modules to an array
1009 930 if ( ! empty( $assoc_args['modules'] ) ) {
1010 931 $modules = array_map( 'trim', explode( ',', $assoc_args['modules'] ) );
1011 932
1012 933 // Convert the array so that the keys are the module name and the value is true to indicate
1013 - // that we want to sync the module.
934 + // that we want to sync the module
1014 935 $modules = array_map( '__return_true', array_flip( $modules ) );
1015 936 }
1016 937
1017 938 foreach ( array( 'posts', 'comments', 'users' ) as $module_name ) {
@@ -1022,9 +943,9 @@
1022 943 ) {
1023 944 $modules['users'] = 'initial';
1024 945 } elseif ( isset( $assoc_args[ $module_name ] ) ) {
1025 946 $ids = explode( ',', $assoc_args[ $module_name ] );
1026 - if ( $ids !== array() ) {
947 + if ( count( $ids ) > 0 ) {
1027 948 $modules[ $module_name ] = $ids;
1028 949 }
1029 950 }
1030 951 }
@@ -1032,13 +953,13 @@
1032 953 if ( empty( $modules ) ) {
1033 954 $modules = null;
1034 955 }
1035 956
1036 - // Kick off a full sync.
957 + // Kick off a full sync
1037 958 if ( Actions::do_full_sync( $modules ) ) {
1038 959 if ( $modules ) {
1039 960 /* translators: %s is a comma separated list of Jetpack modules */
1040 - WP_CLI::log( sprintf( __( 'Initialized a new full sync with modules: %s', 'jetpack' ), implode( ', ', array_keys( $modules ) ) ) );
961 + WP_CLI::log( sprintf( __( 'Initialized a new full sync with modules: %s', 'jetpack' ), join( ', ', array_keys( $modules ) ) ) );
1041 962 } else {
1042 963 WP_CLI::log( __( 'Initialized a new full sync', 'jetpack' ) );
1043 964 }
1044 965 } else {
@@ -1047,37 +968,32 @@
1047 968 Settings::update_settings( $original_settings );
1048 969
1049 970 if ( $modules ) {
1050 971 /* translators: %s is a comma separated list of Jetpack modules */
1051 - WP_CLI::error( sprintf( __( 'Could not start a new full sync with modules: %s', 'jetpack' ), implode( ', ', $modules ) ) );
972 + WP_CLI::error( sprintf( __( 'Could not start a new full sync with modules: %s', 'jetpack' ), join( ', ', $modules ) ) );
1052 973 } else {
1053 974 WP_CLI::error( __( 'Could not start a new full sync', 'jetpack' ) );
1054 975 }
1055 976 }
1056 977
1057 - // Keep sending to WPCOM until there's nothing to send.
978 + // Keep sending to WPCOM until there's nothing to send
1058 979 $i = 1;
1059 980 do {
1060 981 $result = Actions::$sender->do_full_sync();
1061 982 if ( is_wp_error( $result ) ) {
1062 - $queue_empty_error = ( 'empty_queue_full_sync' === $result->get_error_code() );
1063 - if ( ! $queue_empty_error || ( $queue_empty_error && ( 1 === $i ) ) ) {
983 + $queue_empty_error = ( 'empty_queue_full_sync' == $result->get_error_code() );
984 + if ( ! $queue_empty_error || ( $queue_empty_error && ( 1 == $i ) ) ) {
1064 985 /* translators: %s is an error code */
1065 986 WP_CLI::error( sprintf( __( 'Sync errored with code: %s', 'jetpack' ), $result->get_error_code() ) );
1066 987 }
1067 988 } else {
1068 - if ( 1 === $i ) {
989 + if ( 1 == $i ) {
1069 990 WP_CLI::log( __( 'Sent data to WordPress.com', 'jetpack' ) );
1070 991 } else {
1071 992 WP_CLI::log( __( 'Sent more data to WordPress.com', 'jetpack' ) );
1072 993 }
1073 -
1074 - // Immediate Full Sync does not wait for WP.com to process data so we need to enforce a wait.
1075 - if ( str_contains( get_class( Modules::get_module( 'full-sync' ) ), 'Full_Sync_Immediately' ) ) {
1076 - sleep( 15 );
1077 - }
1078 994 }
1079 - ++$i;
995 + $i++;
1080 996 } while ( $result && ! is_wp_error( $result ) );
1081 997
1082 998 // Reset sync settings to original.
1083 999 Settings::update_settings( $original_settings );
@@ -1098,12 +1014,10 @@
1098 1014 *
1099 1015 * wp jetpack sync_queue full_sync peek
1100 1016 *
1101 1017 * @synopsis <incremental|full_sync> <peek>
1102 - *
1103 - * @param array $args Positional args.
1104 1018 */
1105 - public function sync_queue( $args ) {
1019 + public function sync_queue( $args, $assoc_args ) {
1106 1020 if ( ! Actions::sync_allowed() ) {
1107 1021 WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site.', 'jetpack' ) );
1108 1022 }
1109 1023
@@ -1111,13 +1025,12 @@
1111 1025 $action = isset( $args[1] ) ? $args[1] : 'peek';
1112 1026
1113 1027 // We map the queue name that way we can support more friendly queue names in the commands, but still use
1114 1028 // the queue name that the code expects.
1115 - $allowed_queues = array(
1029 + $queue_name_map = $allowed_queues = array(
1116 1030 'incremental' => 'sync',
1117 1031 'full' => 'full_sync',
1118 1032 );
1119 - $queue_name_map = $allowed_queues;
1120 1033 $mapped_queue_name = isset( $queue_name_map[ $queue_name ] ) ? $queue_name_map[ $queue_name ] : $queue_name;
1121 1034
1122 1035 switch ( $action ) {
1123 1036 case 'peek':
@@ -1131,9 +1044,9 @@
1131 1044 $collection = array();
1132 1045 foreach ( $items as $item ) {
1133 1046 $collection[] = array(
1134 1047 'action' => $item[0],
1135 - 'args' => wp_json_encode( $item[1] ),
1048 + 'args' => json_encode( $item[1] ),
1136 1049 'current_user_id' => $item[2],
1137 1050 'microtime' => $item[3],
1138 1051 'importing' => (string) $item[4],
1139 1052 );
@@ -1163,18 +1076,14 @@
1163 1076 * : JSON blob of WPCOM API token
1164 1077 * [--partner_tracking_id=<partner_tracking_id>]
1165 1078 * : This is an optional ID that a host can pass to help identify a site in logs on WordPress.com
1166 1079 *
1167 - * @synopsis <token_json> [--partner_tracking_id=<partner_tracking_id>]
1168 - *
1169 - * @param array $args Positional args.
1170 - * @param array $named_args Named args.
1080 + * * @synopsis <token_json> [--partner_tracking_id=<partner_tracking_id>]
1171 1081 */
1172 1082 public function partner_cancel( $args, $named_args ) {
1173 1083 list( $token_json ) = $args;
1174 1084
1175 - $token = $token_json ? json_decode( $token_json ) : null;
1176 - if ( ! $token ) {
1085 + if ( ! $token_json || ! ( $token = json_decode( $token_json ) ) ) {
1177 1086 /* translators: %s is the invalid JSON string */
1178 1087 $this->partner_provision_error( new WP_Error( 'missing_access_token', sprintf( __( 'Invalid token JSON: %s', 'jetpack' ), $token_json ) ) );
1179 1088 }
1180 1089
@@ -1185,9 +1094,9 @@
1185 1094 if ( ! isset( $token->access_token ) ) {
1186 1095 $this->partner_provision_error( new WP_Error( 'missing_access_token', __( 'Missing or invalid access token', 'jetpack' ) ) );
1187 1096 }
1188 1097
1189 - if ( Identity_Crisis::validate_sync_error_idc_option() ) {
1098 + if ( Jetpack::validate_sync_error_idc_option() ) {
1190 1099 $this->partner_provision_error(
1191 1100 new WP_Error(
1192 1101 'site_in_safe_mode',
1193 1102 esc_html__( 'Can not cancel a plan while in safe mode. See: https://jetpack.com/support/safe-mode/', 'jetpack' )
@@ -1197,10 +1106,9 @@
1197 1106
1198 1107 $site_identifier = Jetpack_Options::get_option( 'id' );
1199 1108
1200 1109 if ( ! $site_identifier ) {
1201 - $status = new Status();
1202 - $site_identifier = $status->get_site_suffix();
1110 + $site_identifier = Jetpack::build_raw_urls( get_home_url() );
1203 1111 }
1204 1112
1205 1113 $request = array(
1206 1114 'headers' => array(
@@ -1210,9 +1118,9 @@
1210 1118 'timeout' => 60,
1211 1119 'method' => 'POST',
1212 1120 );
1213 1121
1214 - $url = sprintf( '%s/rest/v1.3/jpphp/%s/partner-cancel', $this->get_api_host(), $site_identifier );
1122 + $url = sprintf( 'https://%s/rest/v1.3/jpphp/%s/partner-cancel', $this->get_api_host(), $site_identifier );
1215 1123 if ( ! empty( $named_args ) && ! empty( $named_args['partner_tracking_id'] ) ) {
1216 1124 $url = esc_url_raw( add_query_arg( 'partner_tracking_id', $named_args['partner_tracking_id'], $url ) );
1217 1125 }
1218 1126
@@ -1260,17 +1168,13 @@
1260 1168 * $ wp jetpack partner_provision '{ some: "json" }' premium 1
1261 1169 * { success: true }
1262 1170 *
1263 1171 * @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>]
1264 - *
1265 - * @param array $args Positional args.
1266 - * @param array $named_args Named args.
1267 1172 */
1268 1173 public function partner_provision( $args, $named_args ) {
1269 1174 list( $token_json ) = $args;
1270 1175
1271 - $token = $token_json ? json_decode( $token_json ) : null;
1272 - if ( ! $token ) {
1176 + if ( ! $token_json || ! ( $token = json_decode( $token_json ) ) ) {
1273 1177 /* translators: %s is the invalid JSON string */
1274 1178 $this->partner_provision_error( new WP_Error( 'missing_access_token', sprintf( __( 'Invalid token JSON: %s', 'jetpack' ), $token_json ) ) );
1275 1179 }
1276 1180
@@ -1289,10 +1193,10 @@
1289 1193
1290 1194 $body_json = Jetpack_Provision::partner_provision( $token->access_token, $named_args );
1291 1195
1292 1196 if ( is_wp_error( $body_json ) ) {
1293 - WP_CLI::error(
1294 - wp_json_encode(
1197 + error_log(
1198 + json_encode(
1295 1199 array(
1296 1200 'success' => false,
1297 1201 'error_code' => $body_json->get_error_code(),
1298 1202 'error_message' => $body_json->get_error_message(),
@@ -1301,9 +1205,9 @@
1301 1205 );
1302 1206 exit( 1 );
1303 1207 }
1304 1208
1305 - WP_CLI::log( wp_json_encode( $body_json ) );
1209 + WP_CLI::log( json_encode( $body_json ) );
1306 1210 }
1307 1211
1308 1212 /**
1309 1213 * Manages your Jetpack sitemap
@@ -1318,14 +1222,11 @@
1318 1222 * wp jetpack sitemap rebuild
1319 1223 *
1320 1224 * @subcommand sitemap
1321 1225 * @synopsis <rebuild> [--purge]
1322 - *
1323 - * @param array $args Positional args.
1324 - * @param array $assoc_args Named args.
1325 1226 */
1326 1227 public function sitemap( $args, $assoc_args ) {
1327 - if ( ! Jetpack::is_connection_ready() ) {
1228 + if ( ! Jetpack::is_active() ) {
1328 1229 WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1329 1230 }
1330 1231 if ( ! Jetpack::is_module_active( 'sitemaps' ) ) {
1331 1232 WP_CLI::error( __( 'Jetpack Sitemaps module is not currently active. Activate it first if you want to work with sitemaps.', 'jetpack' ) );
@@ -1350,11 +1251,8 @@
1350 1251 *
1351 1252 * wp jetpack authorize_user --token=123456789abcdef
1352 1253 *
1353 1254 * @synopsis --token=<value>
1354 - *
1355 - * @param array $args Positional args.
1356 - * @param array $named_args Named args.
1357 1255 */
1358 1256 public function authorize_user( $args, $named_args ) {
1359 1257 if ( ! is_user_logged_in() ) {
1360 1258 WP_CLI::error( __( 'Please select a user to authorize via the --user global argument.', 'jetpack' ) );
@@ -1363,16 +1261,16 @@
1363 1261 if ( empty( $named_args['token'] ) ) {
1364 1262 WP_CLI::error( __( 'A non-empty token argument must be passed.', 'jetpack' ) );
1365 1263 }
1366 1264
1367 - $is_connection_owner = ! Jetpack::connection()->has_connected_owner();
1368 - $current_user_id = get_current_user_id();
1265 + $is_master_user = ! Jetpack::is_active();
1266 + $current_user_id = get_current_user_id();
1369 1267
1370 - ( new Tokens() )->update_user_token( $current_user_id, sprintf( '%s.%d', $named_args['token'], $current_user_id ), $is_connection_owner );
1268 + Jetpack::update_user_token( $current_user_id, sprintf( '%s.%d', $named_args['token'], $current_user_id ), $is_master_user );
1371 1269
1372 1270 WP_CLI::log( wp_json_encode( $named_args ) );
1373 1271
1374 - if ( $is_connection_owner ) {
1272 + if ( $is_master_user ) {
1375 1273 /**
1376 1274 * Auto-enable SSO module for new Jetpack Start connections
1377 1275 *
1378 1276 * @since 5.0.0
@@ -1420,14 +1318,11 @@
1420 1318 *
1421 1319 * ## EXAMPLES
1422 1320 *
1423 1321 * wp jetpack call_api --resource='/sites/%d'
1424 - *
1425 - * @param array $args Positional args.
1426 - * @param array $named_args Named args.
1427 1322 */
1428 1323 public function call_api( $args, $named_args ) {
1429 - if ( ! Jetpack::is_connection_ready() ) {
1324 + if ( ! Jetpack::is_active() ) {
1430 1325 WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1431 1326 }
1432 1327
1433 1328 $consumed_args = array(
@@ -1444,9 +1339,9 @@
1444 1339 $decoded_body = ! empty( $named_args['body'] )
1445 1340 ? json_decode( $named_args['body'], true )
1446 1341 : false;
1447 1342
1448 - $resource_url = ( ! str_contains( $named_args['resource'], '%d' ) )
1343 + $resource_url = ( false === strpos( $named_args['resource'], '%d' ) )
1449 1344 ? $named_args['resource']
1450 1345 : sprintf( $named_args['resource'], Jetpack_Options::get_option( 'id' ) );
1451 1346
1452 1347 $response = Client::wpcom_json_api_request_as_blog(
@@ -1522,14 +1417,11 @@
1522 1417 * ## EXAMPLES
1523 1418 *
1524 1419 * wp jetpack upload_ssh_creds --host=example.com --ssh-user=example --pass=password
1525 1420 * wp jetpack updload_ssh_creds --host=example.com --ssh-user=example --kpri=key
1526 - *
1527 - * @param array $args Positional args.
1528 - * @param array $named_args Named args.
1529 1421 */
1530 1422 public function upload_ssh_creds( $args, $named_args ) {
1531 - if ( ! Jetpack::is_connection_ready() ) {
1423 + if ( ! Jetpack::is_active() ) {
1532 1424 WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1533 1425 }
1534 1426
1535 1427 $required_args = array(
@@ -1614,11 +1506,8 @@
1614 1506 *
1615 1507 * ## EXAMPLES
1616 1508 *
1617 1509 * wp jetpack get_stats
1618 - *
1619 - * @param array $args Positional args.
1620 - * @param array $named_args Named args.
1621 1510 */
1622 1511 public function get_stats( $args, $named_args ) {
1623 1512 $selected_args = array_intersect_key(
1624 1513 $named_args,
@@ -1689,15 +1578,15 @@
1689 1578 * # List all publicize connections.
1690 1579 * $ wp jetpack publicize list
1691 1580 *
1692 1581 * # List publicize connections for a given service.
1693 - * $ wp jetpack publicize list linkedin
1582 + * $ wp jetpack publicize list twitter
1694 1583 *
1695 1584 * # List all publicize connections for a given user.
1696 1585 * $ wp --user=1 jetpack publicize list
1697 1586 *
1698 1587 * # List all publicize connections for a given user and service.
1699 - * $ wp --user=1 jetpack publicize list linkedin
1588 + * $ wp --user=1 jetpack publicize list twitter
1700 1589 *
1701 1590 * # Display details for a given connection.
1702 1591 * $ wp jetpack publicize list 123456
1703 1592 *
@@ -1707,37 +1596,33 @@
1707 1596 * # Disconnect all connections.
1708 1597 * $ wp jetpack publicize disconnect all
1709 1598 *
1710 1599 * # Disconnect all connections for a given service.
1711 - * $ wp jetpack publicize disconnect linkedin
1712 - *
1713 - * @param array $args Positional args.
1714 - * @param array $named_args Named args.
1600 + * $ wp jetpack publicize disconnect twitter
1715 1601 */
1716 1602 public function publicize( $args, $named_args ) {
1717 - if ( ! Jetpack::connection()->has_connected_owner() ) {
1718 - WP_CLI::error( __( 'Jetpack Social requires a user-level connection to WordPress.com', 'jetpack' ) );
1603 + if ( ! Jetpack::is_active() ) {
1604 + WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1719 1605 }
1720 1606
1721 1607 if ( ! Jetpack::is_module_active( 'publicize' ) ) {
1722 - WP_CLI::error( __( 'The Jetpack Social module is not active.', 'jetpack' ) );
1608 + WP_CLI::error( __( 'The publicize module is not active.', 'jetpack' ) );
1723 1609 }
1724 1610
1725 - if ( ( new Status() )->is_offline_mode() ) {
1611 + if ( Jetpack::is_development_mode() ) {
1726 1612 if (
1727 1613 ! defined( 'JETPACK_DEV_DEBUG' ) &&
1728 1614 ! has_filter( 'jetpack_development_mode' ) &&
1729 - ! has_filter( 'jetpack_offline_mode' ) &&
1730 - ! str_contains( site_url(), '.' )
1615 + false === strpos( site_url(), '.' )
1731 1616 ) {
1732 - 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' ) );
1617 + WP_CLI::error( __( "Jetpack is current in development mode because the site url does not contain a '.', which often occurs when dynamically setting the WP_SITEURL constant. While in development mode, the publicize module will not load.", 'jetpack' ) );
1733 1618 }
1734 1619
1735 - WP_CLI::error( __( 'Jetpack is currently in offline mode, so the Jetpack Social module will not load.', 'jetpack' ) );
1620 + WP_CLI::error( __( 'Jetpack is currently in development mode, so the publicize module will not load.', 'jetpack' ) );
1736 1621 }
1737 1622
1738 1623 if ( ! class_exists( 'Publicize' ) ) {
1739 - WP_CLI::error( __( 'The Jetpack Social module is not loaded.', 'jetpack' ) );
1624 + WP_CLI::error( __( 'The publicize module is not loaded.', 'jetpack' ) );
1740 1625 }
1741 1626
1742 1627 $action = $args[0];
1743 1628 $publicize = new Publicize();
@@ -1820,12 +1705,12 @@
1820 1705 // If the connection ID is 'all' then delete all connections. If the connection ID
1821 1706 // matches a service, delete all connections for that service.
1822 1707 if ( 'all' === $identifier || $id_is_service ) {
1823 1708 if ( 'all' === $identifier ) {
1824 - WP_CLI::log( __( "You're about to delete all Jetpack Social connections.", 'jetpack' ) );
1709 + WP_CLI::log( __( "You're about to delete all publicize connections.", 'jetpack' ) );
1825 1710 } else {
1826 1711 /* translators: %s is a lowercase string for a social network. */
1827 - WP_CLI::log( sprintf( __( "You're about to delete all Jetpack Social connections to %s.", 'jetpack' ), $identifier ) );
1712 + WP_CLI::log( sprintf( __( "You're about to delete all publicize connections to %s.", 'jetpack' ), $identifier ) );
1828 1713 }
1829 1714
1830 1715 jetpack_cli_are_you_sure();
1831 1716
@@ -1846,9 +1731,9 @@
1846 1731 $connections = $option_connections[ $service ];
1847 1732 }
1848 1733
1849 1734 if ( ! empty( $connections ) ) {
1850 - $count = is_countable( $connections ) ? count( $connections ) : 0;
1735 + $count = count( $connections );
1851 1736 $progress = \WP_CLI\Utils\make_progress_bar(
1852 1737 /* translators: %s is a lowercase string for a social network. */
1853 1738 sprintf( __( 'Disconnecting all connections to %s.', 'jetpack' ), $service ),
1854 1739 $count
@@ -1858,9 +1743,9 @@
1858 1743 if ( false === $publicize->disconnect( false, $id ) ) {
1859 1744 WP_CLI::error(
1860 1745 sprintf(
1861 1746 /* translators: %1$d is a numeric ID and %2$s is a lowercase string for a social network. */
1862 - __( 'Jetpack Social connection %d could not be disconnected', 'jetpack' ),
1747 + __( 'Publicize connection %d could not be disconnected', 'jetpack' ),
1863 1748 $id
1864 1749 )
1865 1750 );
1866 1751 }
@@ -1870,43 +1755,35 @@
1870 1755
1871 1756 $progress->finish();
1872 1757
1873 1758 if ( 'all' === $service ) {
1874 - WP_CLI::success( __( 'All Jetpack Social connections were successfully disconnected.', 'jetpack' ) );
1759 + WP_CLI::success( __( 'All publicize connections were successfully disconnected.', 'jetpack' ) );
1875 1760 } else {
1876 1761 /* translators: %s is a lowercase string for a social network. */
1877 - WP_CLI::success( __( 'All Jetpack Social connections to %s were successfully disconnected.', 'jetpack' ), $service );
1762 + WP_CLI::success( __( 'All publicize connections to %s were successfully disconnected.', 'jetpack' ), $service );
1878 1763 }
1879 1764 }
1880 - } elseif ( false !== $publicize->disconnect( false, $identifier ) ) {
1881 - /* translators: %d is a numeric ID. Example: 1234. */
1882 - WP_CLI::success( sprintf( __( 'Jetpack Social connection %d has been disconnected.', 'jetpack' ), $identifier ) );
1883 1765 } else {
1884 - /* translators: %d is a numeric ID. Example: 1234. */
1885 - WP_CLI::error( sprintf( __( 'Jetpack Social connection %d could not be disconnected.', 'jetpack' ), $identifier ) );
1766 + if ( false !== $publicize->disconnect( false, $identifier ) ) {
1767 + /* translators: %d is a numeric ID. Example: 1234. */
1768 + WP_CLI::success( sprintf( __( 'Publicize connection %d has been disconnected.', 'jetpack' ), $identifier ) );
1769 + } else {
1770 + /* translators: %d is a numeric ID. Example: 1234. */
1771 + WP_CLI::error( sprintf( __( 'Publicize connection %d could not be disconnected.', 'jetpack' ), $identifier ) );
1772 + }
1886 1773 }
1887 1774 break; // disconnect.
1888 1775 }
1889 1776 }
1890 1777
1891 - /**
1892 - * Get the API host.
1893 - *
1894 - * @return string URL.
1895 - */
1896 1778 private function get_api_host() {
1897 1779 $env_api_host = getenv( 'JETPACK_START_API_HOST', true );
1898 - return $env_api_host ? 'https://' . $env_api_host : JETPACK__WPCOM_JSON_API_BASE;
1780 + return $env_api_host ? $env_api_host : JETPACK__WPCOM_JSON_API_HOST;
1899 1781 }
1900 1782
1901 - /**
1902 - * Log and exit on a partner provision error.
1903 - *
1904 - * @param WP_Error $error Error.
1905 - */
1906 1783 private function partner_provision_error( $error ) {
1907 1784 WP_CLI::log(
1908 - wp_json_encode(
1785 + json_encode(
1909 1786 array(
1910 1787 'success' => false,
1911 1788 'error_code' => $error->get_error_code(),
1912 1789 'error_message' => $error->get_error_message(),
@@ -1929,9 +1806,8 @@
1929 1806 * The title is also used to create the slug and the edit PHP class name. If it's something like "Logo gallery", the slug will be 'logo-gallery' and the class name will be LogoGalleryEdit.
1930 1807 * --slug: Specific slug to identify the block that overrides the one generated based on the title.
1931 1808 * --description: Allows to provide a text description of the block.
1932 1809 * --keywords: Provide up to three keywords separated by comma so users can find this block when they search in Gutenberg's inserter.
1933 - * --variation: Allows to decide whether the block should be a production block, experimental, or beta. Defaults to Beta when arg not provided.
1934 1810 *
1935 1811 * ## BLOCK TYPE EXAMPLES
1936 1812 *
1937 1813 * wp jetpack scaffold block "Cool Block"
@@ -1936,12 +1812,11 @@
1936 1812 *
1937 1813 * wp jetpack scaffold block "Cool Block"
1938 1814 * wp jetpack scaffold block "Amazing Rock" --slug="good-music" --description="Rock the best music on your site"
1939 1815 * wp jetpack scaffold block "Jukebox" --keywords="music, audio, media"
1940 - * wp jetpack scaffold block "Jukebox" --variation="experimental"
1941 1816 *
1942 1817 * @subcommand scaffold block
1943 - * @synopsis <type> <title> [--slug] [--description] [--keywords] [--variation]
1818 + * @synopsis <type> <title> [--slug] [--description] [--keywords]
1944 1819 *
1945 1820 * @param array $args Positional parameters, when strings are passed, wrap them in quotes.
1946 1821 * @param array $assoc_args Associative parameters like --slug="nice-block".
1947 1822 */
@@ -1975,15 +1850,8 @@
1975 1850 $slug = isset( $assoc_args['slug'] )
1976 1851 ? $assoc_args['slug']
1977 1852 : sanitize_title( $title );
1978 1853
1979 - $next_version = "\x24\x24next-version$$"; // Escapes to hide the string from tools/replace-next-version-tag.sh
1980 -
1981 - $variation_options = array( 'production', 'experimental', 'beta' );
1982 - $variation = ( isset( $assoc_args['variation'] ) && in_array( $assoc_args['variation'], $variation_options, true ) )
1983 - ? $assoc_args['variation']
1984 - : 'beta';
1985 -
1986 1854 if ( preg_match( '#^jetpack/#', $slug ) ) {
1987 1855 $slug = preg_replace( '#^jetpack/#', '', $slug );
1988 1856 }
1989 1857
@@ -2005,40 +1873,41 @@
2005 1873 }
2006 1874
2007 1875 $wp_filesystem->mkdir( $path );
2008 1876
2009 - $keywords = isset( $assoc_args['keywords'] )
2010 - ? array_map(
2011 - function ( $keyword ) {
2012 - return trim( $keyword );
2013 - },
2014 - array_slice( explode( ',', $assoc_args['keywords'] ), 0, 3 )
2015 - )
2016 - : array();
1877 + $hasKeywords = isset( $assoc_args['keywords'] );
2017 1878
2018 1879 $files = array(
2019 - "$path/block.json" => self::render_block_file(
2020 - 'block-block-json',
1880 + "$path/$slug.php" => $this->render_block_file(
1881 + 'block-register-php',
2021 1882 array(
2022 - 'slug' => $slug,
2023 - 'title' => wp_json_encode( $title, JSON_UNESCAPED_UNICODE ),
2024 - 'description' => isset( $assoc_args['description'] )
2025 - ? wp_json_encode( $assoc_args['description'], JSON_UNESCAPED_UNICODE )
2026 - : wp_json_encode( $title, JSON_UNESCAPED_UNICODE ),
2027 - 'nextVersion' => $next_version,
2028 - 'keywords' => wp_json_encode( $keywords, JSON_UNESCAPED_UNICODE ),
1883 + 'slug' => $slug,
1884 + 'title' => $title,
1885 + 'underscoredSlug' => str_replace( '-', '_', $slug ),
2029 1886 )
2030 1887 ),
2031 - "$path/$slug.php" => self::render_block_file(
2032 - 'block-register-php',
1888 + "$path/index.js" => $this->render_block_file(
1889 + 'block-index-js',
2033 1890 array(
2034 - 'nextVersion' => $next_version,
2035 - 'title' => $title,
2036 - 'underscoredTitle' => str_replace( ' ', '_', $title ),
1891 + 'slug' => $slug,
1892 + 'title' => $title,
1893 + 'description' => isset( $assoc_args['description'] )
1894 + ? $assoc_args['description']
1895 + : $title,
1896 + 'keywords' => $hasKeywords
1897 + ? array_map(
1898 + function( $keyword ) {
1899 + // Construction necessary for Mustache lists
1900 + return array( 'keyword' => trim( $keyword ) );
1901 + },
1902 + explode( ',', $assoc_args['keywords'], 3 )
1903 + )
1904 + : '',
1905 + 'hasKeywords' => $hasKeywords,
2037 1906 )
2038 1907 ),
2039 - "$path/editor.js" => self::render_block_file( 'block-editor-js' ),
2040 - "$path/editor.scss" => self::render_block_file(
1908 + "$path/editor.js" => $this->render_block_file( 'block-editor-js' ),
1909 + "$path/editor.scss" => $this->render_block_file(
2041 1910 'block-editor-scss',
2042 1911 array(
2043 1912 'slug' => $slug,
2044 1913 'title' => $title,
@@ -2043,9 +1912,9 @@
2043 1912 'slug' => $slug,
2044 1913 'title' => $title,
2045 1914 )
2046 1915 ),
2047 - "$path/edit.js" => self::render_block_file(
1916 + "$path/edit.js" => $this->render_block_file(
2048 1917 'block-edit-js',
2049 1918 array(
2050 1919 'title' => $title,
2051 1920 'className' => str_replace( ' ', '', ucwords( str_replace( '-', ' ', $slug ) ) ),
@@ -2066,9 +1935,9 @@
2066 1935
2067 1936 if ( empty( $files_written ) ) {
2068 1937 WP_CLI::log( esc_html__( 'No files were created', 'jetpack' ) );
2069 1938 } else {
2070 - // Load index.json and insert the slug of the new block in its block variation array.
1939 + // Load index.json and insert the slug of the new block in the production array
2071 1940 $block_list_path = JETPACK__PLUGIN_DIR . 'extensions/index.json';
2072 1941 $block_list = $wp_filesystem->get_contents( $block_list_path );
2073 1942 if ( empty( $block_list ) ) {
2074 1943 /* translators: %s is the path to the file with the block list */
@@ -2073,39 +1942,16 @@
2073 1942 if ( empty( $block_list ) ) {
2074 1943 /* translators: %s is the path to the file with the block list */
2075 1944 WP_CLI::error( sprintf( esc_html__( 'Error fetching contents of %s', 'jetpack' ), $block_list_path ) );
2076 1945 } elseif ( false === stripos( $block_list, $slug ) ) {
2077 - $new_block_list = json_decode( $block_list );
2078 - $new_block_list->{ $variation }[] = $slug;
2079 -
2080 - // Format the JSON to match our coding standards.
2081 - $new_block_list_formatted = wp_json_encode( $new_block_list, JSON_PRETTY_PRINT ) . "\n";
2082 - $new_block_list_formatted = preg_replace_callback(
2083 - // Find all occurrences of multiples of 4 spaces a the start of the line.
2084 - '/^((?: )+)/m',
2085 - function ( $matches ) {
2086 - // Replace each occurrence of 4 spaces with a tab character.
2087 - return str_repeat( "\t", substr_count( $matches[0], ' ' ) );
2088 - },
2089 - $new_block_list_formatted
2090 - );
2091 -
2092 - if ( ! $wp_filesystem->put_contents( $block_list_path, $new_block_list_formatted ) ) {
1946 + $new_block_list = json_decode( $block_list );
1947 + $new_block_list->beta[] = $slug;
1948 + if ( ! $wp_filesystem->put_contents( $block_list_path, wp_json_encode( $new_block_list ) ) ) {
2093 1949 /* translators: %s is the path to the file with the block list */
2094 1950 WP_CLI::error( sprintf( esc_html__( 'Error writing new %s', 'jetpack' ), $block_list_path ) );
2095 1951 }
2096 1952 }
2097 1953
2098 - if ( 'beta' === $variation || 'experimental' === $variation ) {
2099 - $block_constant = sprintf(
2100 - /* translators: the placeholder is a constant name */
2101 - esc_html__( 'To load the block, add the constant JETPACK_BLOCKS_VARIATION set to %1$s to your wp-config.php file', 'jetpack' ),
2102 - $variation
2103 - );
2104 - } else {
2105 - $block_constant = '';
2106 - }
2107 -
2108 1954 WP_CLI::success(
2109 1955 sprintf(
2110 1956 /* translators: the placeholders are a human readable title, and a series of words separated by dashes */
2111 1957 esc_html__( 'Successfully created block %1$s with slug %2$s', 'jetpack' ) . ' 🎉' . "\n" .
@@ -2110,22 +1956,20 @@
2110 1956 /* translators: the placeholders are a human readable title, and a series of words separated by dashes */
2111 1957 esc_html__( 'Successfully created block %1$s with slug %2$s', 'jetpack' ) . ' 🎉' . "\n" .
2112 1958 "--------------------------------------------------------------------------------------------------------------------\n" .
2113 1959 /* translators: the placeholder is a directory path */
2114 - esc_html__( 'The files were created at %3$s', 'jetpack' ) . "\n" .
2115 - esc_html__( 'To start using the block, build the blocks with pnpm run build-extensions', 'jetpack' ) . "\n" .
1960 + esc_html__( 'The files were created at %s', 'jetpack' ) . "\n" .
1961 + esc_html__( 'To start using the block, build the blocks with yarn run build-extensions', 'jetpack' ) . "\n" .
2116 1962 /* translators: the placeholder is a file path */
2117 - esc_html__( 'The block slug has been added to the %4$s list at %5$s', 'jetpack' ) . "\n" .
2118 - '%6$s' . "\n" .
1963 + esc_html__( 'The block slug has been added to the beta list at %s', 'jetpack' ) . "\n" .
1964 + esc_html__( 'To load the block, add the constant JETPACK_BETA_BLOCKS as true to your wp-config.php file', 'jetpack' ) . "\n" .
2119 1965 /* translators: the placeholder is a URL */
2120 - "\n" . esc_html__( 'Read more at %7$s', 'jetpack' ) . "\n",
1966 + "\n" . esc_html__( 'Read more at %s', 'jetpack' ) . "\n",
2121 1967 $title,
2122 1968 $slug,
2123 1969 $path,
2124 - $variation,
2125 1970 $block_list_path,
2126 - $block_constant,
2127 - 'https://github.com/Automattic/jetpack/blob/trunk/projects/plugins/jetpack/extensions/README.md#developing-block-editor-extensions-in-jetpack'
1971 + 'https://github.com/Automattic/jetpack/blob/master/extensions/README.md#develop-new-blocks'
2128 1972 ) . '--------------------------------------------------------------------------------------------------------------------'
2129 1973 );
2130 1974 }
2131 1975 }
@@ -2132,10 +1976,11 @@
2132 1976
2133 1977 /**
2134 1978 * Built the file replacing the placeholders in the template with the data supplied.
2135 1979 *
2136 - * @param string $template Template.
2137 - * @param array $data Data.
1980 + * @param string $template
1981 + * @param array $data
1982 + *
2138 1983 * @return string mixed
2139 1984 */
2140 1985 private static function render_block_file( $template, $data = array() ) {
2141 1986 return \WP_CLI\Utils\mustache_render( JETPACK__PLUGIN_DIR . "wp-cli-templates/$template.mustache", $data );
@@ -2141,23 +1986,21 @@
2141 1986 return \WP_CLI\Utils\mustache_render( JETPACK__PLUGIN_DIR . "wp-cli-templates/$template.mustache", $data );
2142 1987 }
2143 1988 }
2144 1989
2145 -// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move these functions to some other file.
2146 -
2147 -/**
1990 +/*
2148 1991 * Standard "ask for permission to continue" function.
2149 1992 * If action cancelled, ask if they need help.
2150 1993 *
2151 1994 * Written outside of the class so it's not listed as an executable command w/ 'wp jetpack'
2152 1995 *
2153 - * @param bool $flagged false = normal option | true = flagged by get_jetpack_options_for_reset().
2154 - * @param string $error_msg Error message.
1996 + * @param $flagged bool false = normal option | true = flagged by get_jetpack_options_for_reset()
1997 + * @param $error_msg string (optional)
2155 1998 */
2156 1999 function jetpack_cli_are_you_sure( $flagged = false, $error_msg = false ) {
2157 2000 $cli = new Jetpack_CLI();
2158 2001
2159 - // Default cancellation message.
2002 + // Default cancellation message
2160 2003 if ( ! $error_msg ) {
2161 2004 $error_msg =
2162 2005 __( 'Action cancelled. Have a question?', 'jetpack' )
2163 2006 . ' '
@@ -2168,14 +2011,14 @@
2168 2011
2169 2012 if ( ! $flagged ) {
2170 2013 $prompt_message = _x( 'Are you sure? This cannot be undone. Type "yes" to continue:', '"yes" is a command - do not translate.', 'jetpack' );
2171 2014 } else {
2172 - $prompt_message = _x( 'Are you sure? Modifying this option may disrupt your Jetpack connection. Type "yes" to continue.', '"yes" is a command - do not translate.', 'jetpack' );
2015 + $prompt_message = _x( 'Are you sure? Modifying this option may disrupt your Jetpack connection. Type "yes" to continue.', '"yes" is a command - do not translate.', 'jetpack' );
2173 2016 }
2174 2017
2175 2018 WP_CLI::line( $prompt_message );
2176 2019 $handle = fopen( 'php://stdin', 'r' );
2177 2020 $line = fgets( $handle );
2178 - if ( 'yes' !== trim( $line ) ) {
2021 + if ( 'yes' != trim( $line ) ) {
2179 2022 WP_CLI::error( $error_msg );
2180 2023 }
2181 2024 }