PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 9.2
Jetpack – WP Security, Backup, Speed, & Growth v9.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 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
← All changes | class.jetpack-cli.php +231 -327 14.4.29.2 View file →
@@ -1,18 +1,11 @@
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\Publicize\Connections;
14 -use Automattic\Jetpack\Publicize\Publicize;
7 +use Automattic\Jetpack\Connection\Utils as Connection_Utils;
15 8 use Automattic\Jetpack\Status;
16 9 use Automattic\Jetpack\Sync\Actions;
17 10 use Automattic\Jetpack\Sync\Listener;
18 11 use Automattic\Jetpack\Sync\Modules;
@@ -17,47 +10,17 @@
17 10 use Automattic\Jetpack\Sync\Listener;
18 11 use Automattic\Jetpack\Sync\Modules;
19 12 use Automattic\Jetpack\Sync\Queue;
20 13 use Automattic\Jetpack\Sync\Settings;
21 -use Automattic\Jetpack\Waf\Brute_Force_Protection\Brute_Force_Protection_Shared_Functions;
22 14
23 -if ( ! class_exists( 'WP_CLI_Command' ) ) {
24 - return;
25 -}
26 -
27 -// @phan-suppress-next-line PhanUndeclaredFunctionInCallable -- https://github.com/phan/phan/issues/4763
28 -WP_CLI::add_command( 'jetpack', 'Jetpack_CLI' );
29 -
30 15 /**
31 16 * Control your local Jetpack installation.
32 17 */
33 18 class Jetpack_CLI extends WP_CLI_Command {
34 - /**
35 - * Console escape code for green.
36 - *
37 - * @var string
38 - */
39 - public $green_open = "\033[32m";
40 -
41 - /**
42 - * Console escape code for red.
43 - *
44 - * @var string
45 - */
46 - public $red_open = "\033[31m";
47 -
48 - /**
49 - * Console escape code for yellow.
50 - *
51 - * @var string
52 - */
19 + // Aesthetics.
20 + public $green_open = "\033[32m";
21 + public $red_open = "\033[31m";
53 22 public $yellow_open = "\033[33m";
54 -
55 - /**
56 - * Console escape code to reset coloring.
57 - *
58 - * @var string
59 - */
60 23 public $color_close = "\033[0m";
61 24
62 25 /**
63 26 * Get Jetpack Details
@@ -71,13 +34,11 @@
71 34 * ## EXAMPLES
72 35 *
73 36 * wp jetpack status
74 37 * wp jetpack status full
75 - *
76 - * @param array $args Positional args.
77 38 */
78 - public function status( $args ) {
79 - require_once JETPACK__PLUGIN_DIR . '_inc/lib/debugger.php';
39 + public function status( $args, $assoc_args ) {
40 + jetpack_require_lib( 'debugger' );
80 41
81 42 /* translators: %s is the site URL */
82 43 WP_CLI::line( sprintf( __( 'Checking status for %s', 'jetpack' ), esc_url( get_home_url() ) ) );
83 44
@@ -96,9 +57,9 @@
96 57 WP_CLI::success( __( 'Jetpack is currently connected to WordPress.com', 'jetpack' ) );
97 58 } else {
98 59 $error = array();
99 60 foreach ( $cxntests->list_fails() as $fail ) {
100 - $error[] = $fail['name'] . ( empty( $fail['message'] ) ? '' : ': ' . $fail['message'] );
61 + $error[] = $fail['name'] . ': ' . $fail['message'];
101 62 }
102 63 WP_CLI::error_multi_line( $error );
103 64
104 65 $cxntests->output_results_for_cli();
@@ -117,41 +78,41 @@
117 78 * Are they asking for all data?
118 79 *
119 80 * Loop through heartbeat data and organize by priority.
120 81 */
121 - $all_data = ( isset( $args[0] ) && 'full' === $args[0] ) ? 'full' : false;
82 + $all_data = ( isset( $args[0] ) && 'full' == $args[0] ) ? 'full' : false;
122 83 if ( $all_data ) {
123 - // Heartbeat data.
84 + // Heartbeat data
124 85 WP_CLI::line( "\n" . __( 'Additional data: ', 'jetpack' ) );
125 86
126 87 // Get the filtered heartbeat data.
127 - // Filtered so we can color/list by severity.
88 + // Filtered so we can color/list by severity
128 89 $stats = Jetpack::jetpack_check_heartbeat_data();
129 90
130 - // Display red flags first.
91 + // Display red flags first
131 92 foreach ( $stats['bad'] as $stat => $value ) {
132 - WP_CLI::line( sprintf( "$this->red_open%-'.16s %s $this->color_close", $stat, $value ) );
93 + printf( "$this->red_open%-'.16s %s $this->color_close\n", $stat, $value );
133 94 }
134 95
135 - // Display caution warnings next.
96 + // Display caution warnings next
136 97 foreach ( $stats['caution'] as $stat => $value ) {
137 - WP_CLI::line( sprintf( "$this->yellow_open%-'.16s %s $this->color_close", $stat, $value ) );
98 + printf( "$this->yellow_open%-'.16s %s $this->color_close\n", $stat, $value );
138 99 }
139 100
140 101 // The rest of the results are good!
141 102 foreach ( $stats['good'] as $stat => $value ) {
142 103
143 - // Modules should get special spacing for aestetics.
104 + // Modules should get special spacing for aestetics
144 105 if ( strpos( $stat, 'odule-' ) ) {
145 - WP_CLI::line( sprintf( "%-'.30s %s", $stat, $value ) );
146 - usleep( 4000 ); // For dramatic effect lolz.
106 + printf( "%-'.30s %s\n", $stat, $value );
107 + usleep( 4000 ); // For dramatic effect lolz
147 108 continue;
148 109 }
149 - WP_CLI::line( sprintf( "%-'.16s %s", $stat, $value ) );
150 - usleep( 4000 ); // For dramatic effect lolz.
110 + printf( "%-'.16s %s\n", $stat, $value );
111 + usleep( 4000 ); // For dramatic effect lolz
151 112 }
152 113 } else {
153 - // Just the basics.
114 + // Just the basics
154 115 WP_CLI::line( "\n" . _x( "View full status with 'wp jetpack status full'", '"wp jetpack status full" is a command - do not translate', 'jetpack' ) );
155 116 }
156 117 }
157 118
@@ -165,14 +126,14 @@
165 126 * wp jetpack test-connection
166 127 *
167 128 * @subcommand test-connection
168 129 */
169 - public function test_connection() {
130 + public function test_connection( $args, $assoc_args ) {
170 131
171 132 /* translators: %s is the site URL */
172 133 WP_CLI::line( sprintf( __( 'Testing connection for %s', 'jetpack' ), esc_url( get_site_url() ) ) );
173 134
174 - if ( ! Jetpack::is_connection_ready() ) {
135 + if ( ! Jetpack::is_active() ) {
175 136 WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
176 137 }
177 138
178 139 $response = Client::wpcom_json_api_request_as_blog(
@@ -209,38 +170,34 @@
209 170 * blog: Disconnect the entire blog.
210 171 *
211 172 * user <user_identifier>: Disconnect a specific user from WordPress.com.
212 173 *
213 - * [--force]
214 - * If the user ID provided is the connection owner, it will only be disconnected if --force is passed
174 + * Please note, the primary account that the blog is connected
175 + * to WordPress.com with cannot be disconnected without
176 + * disconnecting the entire blog.
215 177 *
216 178 * ## EXAMPLES
217 179 *
218 180 * wp jetpack disconnect blog
219 181 * wp jetpack disconnect user 13
220 - * wp jetpack disconnect user 1 --force
221 182 * wp jetpack disconnect user username
222 183 * wp jetpack disconnect user email@domain.com
223 184 *
224 - * @synopsis <blog|user> [<user_identifier>] [--force]
225 - *
226 - * @param array $args Positional args.
227 - * @param array $assoc_args Named args.
185 + * @synopsis <blog|user> [<user_identifier>]
228 186 */
229 187 public function disconnect( $args, $assoc_args ) {
230 - $user = null;
231 - if ( ! Jetpack::is_connection_ready() ) {
188 + if ( ! Jetpack::is_active() ) {
232 189 WP_CLI::success( __( 'The site is not currently connected, so nothing to do!', 'jetpack' ) );
233 190 return;
234 191 }
235 192
236 193 $action = isset( $args[0] ) ? $args[0] : 'prompt';
237 - if ( ! in_array( $action, array( 'blog', 'user', 'prompt' ), true ) ) {
194 + if ( ! in_array( $action, array( 'blog', 'user', 'prompt' ) ) ) {
238 195 /* translators: %s is a command like "prompt" */
239 196 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
240 197 }
241 198
242 - if ( in_array( $action, array( 'user' ), true ) ) {
199 + if ( in_array( $action, array( 'user' ) ) ) {
243 200 if ( isset( $args[1] ) ) {
244 201 $user_id = $args[1];
245 202 if ( ctype_digit( $user_id ) ) {
246 203 $field = 'id';
@@ -251,10 +208,9 @@
251 208 } else {
252 209 $field = 'login';
253 210 $user_id = sanitize_user( $user_id, true );
254 211 }
255 - $user = get_user_by( $field, $user_id );
256 - if ( ! $user ) {
212 + if ( ! $user = get_user_by( $field, $user_id ) ) {
257 213 WP_CLI::error( __( 'Please specify a valid user.', 'jetpack' ) );
258 214 }
259 215 } else {
260 216 WP_CLI::error( __( 'Please specify a user by either ID, username, or email.', 'jetpack' ) );
@@ -260,14 +216,12 @@
260 216 WP_CLI::error( __( 'Please specify a user by either ID, username, or email.', 'jetpack' ) );
261 217 }
262 218 }
263 219
264 - $force_user_disconnect = ! empty( $assoc_args['force'] );
265 -
266 220 switch ( $action ) {
267 221 case 'blog':
268 222 Jetpack::log( 'disconnect' );
269 - ( new Connection_Manager( 'jetpack' ) )->disconnect_site();
223 + Jetpack::disconnect();
270 224 WP_CLI::success(
271 225 sprintf(
272 226 /* translators: %s is the site URL */
273 227 __( 'Jetpack has been successfully disconnected for %s.', 'jetpack' ),
@@ -275,25 +229,14 @@
275 229 )
276 230 );
277 231 break;
278 232 case 'user':
279 - $connection_manager = new Connection_Manager( 'jetpack' );
280 - $disconnected = $connection_manager->disconnect_user( $user->ID, $force_user_disconnect );
281 - if ( $disconnected ) {
233 + if ( Connection_Manager::disconnect_user( $user->ID ) ) {
282 234 Jetpack::log( 'unlink', $user->ID );
283 235 WP_CLI::success( __( 'User has been successfully disconnected.', 'jetpack' ) );
284 236 } else {
285 - if ( ! $connection_manager->is_user_connected( $user->ID ) ) {
286 - /* translators: %s is a username */
287 - $error_message = sprintf( __( 'User %s could not be disconnected because it is not connected!', 'jetpack' ), "{$user->data->user_login} <{$user->data->user_email}>" );
288 - } elseif ( ! $force_user_disconnect && $connection_manager->is_connection_owner( $user->ID ) ) {
289 - /* translators: %s is a username */
290 - $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}>" );
291 - } else {
292 - /* translators: %s is a username */
293 - $error_message = sprintf( __( 'User %s could not be disconnected.', 'jetpack' ), "{$user->data->user_login} <{$user->data->user_email}>" );
294 - }
295 - WP_CLI::error( $error_message );
237 + /* translators: %s is a username */
238 + WP_CLI::error( sprintf( __( "User %s could not be disconnected. Are you sure they're connected currently?", 'jetpack' ), "{$user->login} <{$user->email}>" ) );
296 239 }
297 240 break;
298 241 case 'prompt':
299 242 WP_CLI::error( __( 'Please specify if you would like to disconnect a blog or user.', 'jetpack' ) );
@@ -321,11 +264,8 @@
321 264 * wp jetpack reset modules
322 265 * wp jetpack reset sync-checksum --dry-run --offset=0
323 266 *
324 267 * @synopsis <modules|options|sync-checksum> [--dry-run] [--offset=<offset>]
325 - *
326 - * @param array $args Positional args.
327 - * @param array $assoc_args Named args.
328 268 */
329 269 public function reset( $args, $assoc_args ) {
330 270 $action = isset( $args[0] ) ? $args[0] : 'prompt';
331 271 if ( ! in_array( $action, array( 'options', 'modules', 'sync-checksum' ), true ) ) {
@@ -348,9 +288,9 @@
348 288
349 289 switch ( $action ) {
350 290 case 'options':
351 291 $options_to_reset = Jetpack_Options::get_options_for_reset();
352 - // Reset the Jetpack options.
292 + // Reset the Jetpack options
353 293 WP_CLI::line(
354 294 sprintf(
355 295 /* translators: %s is the site URL */
356 296 __( "Resetting Jetpack Options for %s...\n", 'jetpack' ),
@@ -356,9 +296,9 @@
356 296 __( "Resetting Jetpack Options for %s...\n", 'jetpack' ),
357 297 esc_url( get_site_url() )
358 298 )
359 299 );
360 - sleep( 1 ); // Take a breath.
300 + sleep( 1 ); // Take a breath
361 301 foreach ( $options_to_reset['jp_options'] as $option_to_reset ) {
362 302 if ( ! $is_dry_run ) {
363 303 Jetpack_Options::delete_option( $option_to_reset );
364 304 usleep( 100000 );
@@ -367,11 +307,11 @@
367 307 /* translators: This is the result of an action. The option named %s was reset */
368 308 WP_CLI::success( sprintf( __( '%s option reset', 'jetpack' ), $option_to_reset ) );
369 309 }
370 310
371 - // Reset the WP options.
311 + // Reset the WP options
372 312 WP_CLI::line( __( "Resetting the jetpack options stored in wp_options...\n", 'jetpack' ) );
373 - usleep( 500000 ); // Take a breath.
313 + usleep( 500000 ); // Take a breath
374 314 foreach ( $options_to_reset['wp_options'] as $option_to_reset ) {
375 315 if ( ! $is_dry_run ) {
376 316 delete_option( $option_to_reset );
377 317 usleep( 100000 );
@@ -379,11 +319,11 @@
379 319 /* translators: This is the result of an action. The option named %s was reset */
380 320 WP_CLI::success( sprintf( __( '%s option reset', 'jetpack' ), $option_to_reset ) );
381 321 }
382 322
383 - // Reset to default modules.
323 + // Reset to default modules
384 324 WP_CLI::line( __( "Resetting default modules...\n", 'jetpack' ) );
385 - usleep( 500000 ); // Take a breath.
325 + usleep( 500000 ); // Take a breath
386 326 $default_modules = Jetpack::get_default_modules();
387 327 if ( ! $is_dry_run ) {
388 328 Jetpack::update_active_modules( $default_modules );
389 329 }
@@ -432,9 +372,9 @@
432 372 $option,
433 373 "{$site->domain}{$site->path}"
434 374 )
435 375 );
436 - ++$count_fixes;
376 + $count_fixes++;
437 377 if ( ! $is_dry_run ) {
438 378 /*
439 379 * We could be deleting a lot of options rows at the same time.
440 380 * Allow some time for replication to catch up.
@@ -498,8 +438,9 @@
498 438 "SELECT COUNT(*) FROM $wpdb->options WHERE option_name = %s",
499 439 $option
500 440 )
501 441 );
442 +
502 443 }
503 444
504 445 /**
505 446 * Manage Jetpack Modules
@@ -541,15 +482,11 @@
541 482 * wp jetpack module deactivate stats
542 483 * wp jetpack module toggle stats
543 484 * wp jetpack module activate all
544 485 * wp jetpack module deactivate all
545 - *
546 - * @param array $args Positional args.
547 - * @param array $assoc_args Named args.
548 486 */
549 487 public function module( $args, $assoc_args ) {
550 - $module_slug = null;
551 - $action = isset( $args[0] ) ? $args[0] : 'list';
488 + $action = isset( $args[0] ) ? $args[0] : 'list';
552 489
553 490 if ( isset( $args[1] ) ) {
554 491 $module_slug = $args[1];
555 492 if ( 'all' !== $module_slug && ! Jetpack::is_module( $module_slug ) ) {
@@ -636,18 +573,16 @@
636 573 * wp jetpack protect allow list
637 574 * wp jetpack protect allow clear
638 575 *
639 576 * @synopsis <allow> [<ip|ip_low-ip_high|list|clear>]
640 - *
641 - * @param array $args Positional args.
642 577 */
643 - public function protect( $args ) {
578 + public function protect( $args, $assoc_args ) {
644 579 $action = isset( $args[0] ) ? $args[0] : 'prompt';
645 580 if ( ! in_array( $action, array( 'whitelist', 'allow' ), true ) ) { // Still allow "whitelist" for legacy support.
646 581 /* translators: %s is a command like "prompt" */
647 582 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
648 583 }
649 - // Check if module is active.
584 + // Check if module is active
650 585 if ( ! Jetpack::is_module_active( __FUNCTION__ ) ) {
651 586 /* translators: %s is a module name */
652 587 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__ ) );
653 588 }
@@ -664,17 +599,17 @@
664 599 $new_ip = $args[1];
665 600 $current_allow = get_site_option( 'jetpack_protect_whitelist', array() ); // @todo Update the option name.
666 601
667 602 // Build array of IPs that are already on the allowed list.
668 - // Re-build manually instead of using jetpack_protect_format_allow_list() so we can easily get
669 - // low & high range params for IP_Utils::ip_address_is_in_range().
603 + // Re-build manually instead of using jetpack_protect_format_whitelist() so we can easily get
604 + // low & high range params for jetpack_protect_ip_address_is_in_range();
670 605 foreach ( $current_allow as $allowed ) {
671 606
672 - // IP ranges.
607 + // IP ranges
673 608 if ( $allowed->range ) {
674 609
675 610 // Is it already on the allowed list?
676 - if ( IP_Utils::ip_address_is_in_range( $new_ip, $allowed->range_low, $allowed->range_high ) ) {
611 + if ( jetpack_protect_ip_address_is_in_range( $new_ip, $allowed->range_low, $allowed->range_high ) ) {
677 612 /* translators: %s is an IP address */
678 613 WP_CLI::error( sprintf( __( '%s is already on the always allow list.', 'jetpack' ), $new_ip ) );
679 614 break;
680 615 }
@@ -679,9 +614,9 @@
679 614 break;
680 615 }
681 616 $allow[] = $allowed->range_low . ' - ' . $allowed->range_high;
682 617
683 - } else { // Individual IPs.
618 + } else { // Individual IPs
684 619
685 620 // Check if the IP is already on the allow list (single IP only).
686 621 if ( $new_ip === $allowed->ip_address ) {
687 622 /* translators: %s is an IP address */
@@ -696,9 +631,9 @@
696 631 /*
697 632 * List the allowed IPs.
698 633 * Done here because it's easier to read the $allow array after it's been rebuilt.
699 634 */
700 - if ( isset( $args[1] ) && 'list' === $args[1] ) {
635 + if ( isset( $args[1] ) && 'list' == $args[1] ) {
701 636 if ( ! empty( $allow ) ) {
702 637 WP_CLI::success( __( 'Here are your always allowed IPs:', 'jetpack' ) );
703 638 foreach ( $allow as $ip ) {
704 639 WP_CLI::line( "\t" . str_pad( $ip, 24 ) );
@@ -711,12 +646,12 @@
711 646
712 647 /*
713 648 * Clear the always allow list.
714 649 */
715 - if ( isset( $args[1] ) && 'clear' === $args[1] ) {
650 + if ( isset( $args[1] ) && 'clear' == $args[1] ) {
716 651 if ( ! empty( $allow ) ) {
717 652 $allow = array();
718 - Brute_Force_Protection_Shared_Functions::save_allow_list( $allow ); // @todo Need to update function name in the Protect module.
653 + jetpack_protect_save_whitelist( $allow ); // @todo Need to update function name in the Protect module.
719 654 WP_CLI::success( __( 'Cleared all IPs from the always allow list.', 'jetpack' ) );
720 655 } else {
721 656 WP_CLI::line( __( 'Always allow list is empty.', 'jetpack' ) );
722 657 }
@@ -726,9 +661,9 @@
726 661 // Append new IP to allow array.
727 662 array_push( $allow, $new_ip );
728 663
729 664 // Save allow list if there are no errors.
730 - $result = Brute_Force_Protection_Shared_Functions::save_allow_list( $allow ); // @todo Need to update function name in the Protect module.
665 + $result = jetpack_protect_save_whitelist( $allow ); // @todo Need to update function name in the Protect module.
731 666 if ( is_wp_error( $result ) ) {
732 667 WP_CLI::error( $result );
733 668 }
734 669
@@ -738,9 +673,9 @@
738 673 case 'prompt':
739 674 WP_CLI::error(
740 675 __( 'No command found.', 'jetpack' ) . "\n" .
741 676 __( 'Please enter the IP address you want to always allow.', 'jetpack' ) . "\n" .
742 - _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" .
677 + _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" .
743 678 _x( "You can also 'list' or 'clear' the always allowed list.", "'list' and 'clear' are commands and should not be translated", 'jetpack' ) . "\n"
744 679 );
745 680 break;
746 681 }
@@ -765,29 +700,27 @@
765 700 * wp jetpack options delete <option_name>
766 701 * wp jetpack options update <option_name> [<option_value>]
767 702 *
768 703 * @synopsis <list|get|delete|update> [<option_name>] [<option_value>]
769 - *
770 - * @param array $args Positional args.
771 704 */
772 - public function options( $args ) {
705 + public function options( $args, $assoc_args ) {
773 706 $action = isset( $args[0] ) ? $args[0] : 'list';
774 707 $safe_to_modify = Jetpack_Options::get_options_for_reset();
775 708
776 709 // Is the option flagged as unsafe?
777 - $flagged = ! in_array( $args[1], $safe_to_modify, true );
710 + $flagged = ! in_array( $args[1], $safe_to_modify );
778 711
779 - if ( ! in_array( $action, array( 'list', 'get', 'delete', 'update' ), true ) ) {
712 + if ( ! in_array( $action, array( 'list', 'get', 'delete', 'update' ) ) ) {
780 713 /* translators: %s is a command like "prompt" */
781 714 WP_CLI::error( sprintf( __( '%s is not a valid command.', 'jetpack' ), $action ) );
782 715 }
783 716
784 717 if ( isset( $args[0] ) ) {
785 - if ( 'get' === $args[0] && isset( $args[1] ) ) {
718 + if ( 'get' == $args[0] && isset( $args[1] ) ) {
786 719 $action = 'get';
787 - } elseif ( 'delete' === $args[0] && isset( $args[1] ) ) {
720 + } elseif ( 'delete' == $args[0] && isset( $args[1] ) ) {
788 721 $action = 'delete';
789 - } elseif ( 'update' === $args[0] && isset( $args[1] ) ) {
722 + } elseif ( 'update' == $args[0] && isset( $args[1] ) ) {
790 723 $action = 'update';
791 724 } else {
792 725 $action = 'list';
793 726 }
@@ -792,18 +725,17 @@
792 725 $action = 'list';
793 726 }
794 727 }
795 728
796 - // Bail if the option isn't found.
729 + // Bail if the option isn't found
797 730 $option = isset( $args[1] ) ? Jetpack_Options::get_option( $args[1] ) : false;
798 731 if ( isset( $args[1] ) && ! $option && 'update' !== $args[0] ) {
799 - WP_CLI::error( __( 'Option not found or is empty. Use "list" to list option names', 'jetpack' ) );
732 + WP_CLI::error( __( 'Option not found or is empty. Use "list" to list option names', 'jetpack' ) );
800 733 }
801 734
802 - // Let's print_r the option if it's an array.
803 - // Used in the 'get' and 'list' actions.
804 - // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_print_r
805 - $option = is_array( $option ) ? print_r( $option, true ) : $option;
735 + // Let's print_r the option if it's an array
736 + // Used in the 'get' and 'list' actions
737 + $option = is_array( $option ) ? print_r( $option ) : $option;
806 738
807 739 switch ( $action ) {
808 740 case 'get':
809 741 WP_CLI::success( "\t" . $option );
@@ -833,14 +765,14 @@
833 765 $options_non_compact = Jetpack_Options::get_option_names( 'non_compact' );
834 766 $options_private = Jetpack_Options::get_option_names( 'private' );
835 767 $options = array_merge( $options_compact, $options_non_compact, $options_private );
836 768
837 - // Table headers.
769 + // Table headers
838 770 WP_CLI::line( "\t" . str_pad( __( 'Option', 'jetpack' ), 30 ) . __( 'Value', 'jetpack' ) );
839 771
840 - // List out the options and their values.
841 - // Tell them if the value is empty or not.
842 - // Tell them if it's an array.
772 + // List out the options and their values
773 + // Tell them if the value is empty or not
774 + // Tell them if it's an array
843 775 foreach ( $options as $option ) {
844 776 $value = Jetpack_Options::get_option( $option );
845 777 if ( ! $value ) {
846 778 WP_CLI::line( "\t" . str_pad( $option, 30 ) . 'Empty' );
@@ -859,9 +791,9 @@
859 791 WP_CLI::success(
860 792 _x( "Above are your options. You may 'get', 'delete', and 'update' them.", "'get', 'delete', and 'update' are commands - do not translate.", 'jetpack' ) . "\n" .
861 793 str_pad( 'wp jetpack options get', 26 ) . $option_text . "\n" .
862 794 str_pad( 'wp jetpack options delete', 26 ) . $option_text . "\n" .
863 - str_pad( 'wp jetpack options update', 26 ) . "$option_text $value_text\n" .
795 + str_pad( 'wp jetpack options update', 26 ) . "$option_text $value_text" . "\n" .
864 796 _x( "Type 'wp jetpack options' for more info.", "'wp jetpack options' is a command - do not translate.", 'jetpack' ) . "\n"
865 797 );
866 798 break;
867 799 }
@@ -889,11 +821,8 @@
889 821 * wp jetpack sync reset
890 822 * wp jetpack sync reset --queue=full or regular
891 823 *
892 824 * @synopsis <status|start> [--<field>=<value>]
893 - *
894 - * @param array $args Positional args.
895 - * @param array $assoc_args Named args.
896 825 */
897 826 public function sync( $args, $assoc_args ) {
898 827
899 828 $action = isset( $args[0] ) ? $args[0] : 'status';
@@ -904,9 +833,9 @@
904 833 $collection = array();
905 834 foreach ( $status as $key => $item ) {
906 835 $collection[] = array(
907 836 'option' => $key,
908 - 'value' => is_scalar( $item ) ? $item : wp_json_encode( $item ),
837 + 'value' => is_scalar( $item ) ? $item : json_encode( $item ),
909 838 );
910 839 }
911 840 WP_CLI::log( __( 'Sync Status:', 'jetpack' ) );
912 841 WP_CLI\Utils\format_items( 'table', $collection, array( 'option', 'value' ) );
@@ -912,17 +841,16 @@
912 841 WP_CLI\Utils\format_items( 'table', $collection, array( 'option', 'value' ) );
913 842 break;
914 843 case 'settings':
915 844 WP_CLI::log( __( 'Sync Settings:', 'jetpack' ) );
916 - $settings = array();
917 845 foreach ( Settings::get_settings() as $setting => $item ) {
918 846 $settings[] = array(
919 847 'setting' => $setting,
920 - 'value' => is_scalar( $item ) ? $item : wp_json_encode( $item ),
848 + 'value' => is_scalar( $item ) ? $item : json_encode( $item ),
921 849 );
922 850 }
923 851 WP_CLI\Utils\format_items( 'table', $settings, array( 'setting', 'value' ) );
924 - break;
852 +
925 853 case 'disable':
926 854 // Don't set it via the Settings since that also resets the queues.
927 855 update_option( 'jetpack_sync_settings_disable', 1 );
928 856 /* translators: %s is the site URL */
@@ -968,18 +896,15 @@
968 896
969 897 break;
970 898 case 'start':
971 899 if ( ! Actions::sync_allowed() ) {
972 - if ( Settings::get_setting( 'disable' ) ) {
900 + if ( ! Settings::get_setting( 'disable' ) ) {
973 901 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' ) );
974 902 return;
975 903 }
976 - $connection = new Connection_Manager();
977 - if ( ! $connection->is_connected() ) {
978 - if ( ! doing_action( 'jetpack_site_registered' ) ) {
979 - WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. Jetpack is not connected.', 'jetpack' ) );
980 - return;
981 - }
904 + if ( doing_action( 'jetpack_user_authorized' ) || Jetpack::is_active() ) {
905 + WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. Jetpack is not connected.', 'jetpack' ) );
906 + return;
982 907 }
983 908
984 909 $status = new Status();
985 910
@@ -986,17 +911,17 @@
986 911 if ( $status->is_offline_mode() ) {
987 912 WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in offline mode.', 'jetpack' ) );
988 913 return;
989 914 }
990 - if ( $status->in_safe_mode() ) {
991 - WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in safe mode.', 'jetpack' ) );
915 + if ( $status->is_staging_site() ) {
916 + WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site. The site is in staging mode.', 'jetpack' ) );
992 917 return;
993 918 }
994 919 }
995 - // Get the original settings so that we can restore them later.
920 + // Get the original settings so that we can restore them later
996 921 $original_settings = Settings::get_settings();
997 922
998 - // Initialize sync settigns so we can sync as quickly as possible.
923 + // Initialize sync settigns so we can sync as quickly as possible
999 924 $sync_settings = wp_parse_args(
1000 925 array_intersect_key( $assoc_args, Settings::$valid_settings ),
1001 926 array(
1002 927 'sync_wait_time' => 0,
@@ -1007,14 +932,14 @@
1007 932 )
1008 933 );
1009 934 Settings::update_settings( $sync_settings );
1010 935
1011 - // Convert comma-delimited string of modules to an array.
936 + // Convert comma-delimited string of modules to an array
1012 937 if ( ! empty( $assoc_args['modules'] ) ) {
1013 938 $modules = array_map( 'trim', explode( ',', $assoc_args['modules'] ) );
1014 939
1015 940 // Convert the array so that the keys are the module name and the value is true to indicate
1016 - // that we want to sync the module.
941 + // that we want to sync the module
1017 942 $modules = array_map( '__return_true', array_flip( $modules ) );
1018 943 }
1019 944
1020 945 foreach ( array( 'posts', 'comments', 'users' ) as $module_name ) {
@@ -1025,9 +950,9 @@
1025 950 ) {
1026 951 $modules['users'] = 'initial';
1027 952 } elseif ( isset( $assoc_args[ $module_name ] ) ) {
1028 953 $ids = explode( ',', $assoc_args[ $module_name ] );
1029 - if ( $ids !== array() ) {
954 + if ( count( $ids ) > 0 ) {
1030 955 $modules[ $module_name ] = $ids;
1031 956 }
1032 957 }
1033 958 }
@@ -1035,13 +960,13 @@
1035 960 if ( empty( $modules ) ) {
1036 961 $modules = null;
1037 962 }
1038 963
1039 - // Kick off a full sync.
1040 - if ( Actions::do_full_sync( $modules, 'jetpack_cli' ) ) {
964 + // Kick off a full sync
965 + if ( Actions::do_full_sync( $modules ) ) {
1041 966 if ( $modules ) {
1042 967 /* translators: %s is a comma separated list of Jetpack modules */
1043 - WP_CLI::log( sprintf( __( 'Initialized a new full sync with modules: %s', 'jetpack' ), implode( ', ', array_keys( $modules ) ) ) );
968 + WP_CLI::log( sprintf( __( 'Initialized a new full sync with modules: %s', 'jetpack' ), join( ', ', array_keys( $modules ) ) ) );
1044 969 } else {
1045 970 WP_CLI::log( __( 'Initialized a new full sync', 'jetpack' ) );
1046 971 }
1047 972 } else {
@@ -1050,26 +975,26 @@
1050 975 Settings::update_settings( $original_settings );
1051 976
1052 977 if ( $modules ) {
1053 978 /* translators: %s is a comma separated list of Jetpack modules */
1054 - WP_CLI::error( sprintf( __( 'Could not start a new full sync with modules: %s', 'jetpack' ), implode( ', ', $modules ) ) );
979 + WP_CLI::error( sprintf( __( 'Could not start a new full sync with modules: %s', 'jetpack' ), join( ', ', $modules ) ) );
1055 980 } else {
1056 981 WP_CLI::error( __( 'Could not start a new full sync', 'jetpack' ) );
1057 982 }
1058 983 }
1059 984
1060 - // Keep sending to WPCOM until there's nothing to send.
985 + // Keep sending to WPCOM until there's nothing to send
1061 986 $i = 1;
1062 987 do {
1063 988 $result = Actions::$sender->do_full_sync();
1064 989 if ( is_wp_error( $result ) ) {
1065 - $queue_empty_error = ( 'empty_queue_full_sync' === $result->get_error_code() );
1066 - if ( ! $queue_empty_error || ( $queue_empty_error && ( 1 === $i ) ) ) {
990 + $queue_empty_error = ( 'empty_queue_full_sync' == $result->get_error_code() );
991 + if ( ! $queue_empty_error || ( $queue_empty_error && ( 1 == $i ) ) ) {
1067 992 /* translators: %s is an error code */
1068 993 WP_CLI::error( sprintf( __( 'Sync errored with code: %s', 'jetpack' ), $result->get_error_code() ) );
1069 994 }
1070 995 } else {
1071 - if ( 1 === $i ) {
996 + if ( 1 == $i ) {
1072 997 WP_CLI::log( __( 'Sent data to WordPress.com', 'jetpack' ) );
1073 998 } else {
1074 999 WP_CLI::log( __( 'Sent more data to WordPress.com', 'jetpack' ) );
1075 1000 }
@@ -1074,13 +999,13 @@
1074 999 WP_CLI::log( __( 'Sent more data to WordPress.com', 'jetpack' ) );
1075 1000 }
1076 1001
1077 1002 // Immediate Full Sync does not wait for WP.com to process data so we need to enforce a wait.
1078 - if ( Modules::get_module( 'full-sync' ) instanceof \Automattic\Jetpack\Sync\Modules\Full_Sync_Immediately ) {
1003 + if ( false !== strpos( get_class( Modules::get_module( 'full-sync' ) ), 'Full_Sync_Immediately' ) ) {
1079 1004 sleep( 15 );
1080 1005 }
1081 1006 }
1082 - ++$i;
1007 + $i++;
1083 1008 } while ( $result && ! is_wp_error( $result ) );
1084 1009
1085 1010 // Reset sync settings to original.
1086 1011 Settings::update_settings( $original_settings );
@@ -1101,12 +1026,10 @@
1101 1026 *
1102 1027 * wp jetpack sync_queue full_sync peek
1103 1028 *
1104 1029 * @synopsis <incremental|full_sync> <peek>
1105 - *
1106 - * @param array $args Positional args.
1107 1030 */
1108 - public function sync_queue( $args ) {
1031 + public function sync_queue( $args, $assoc_args ) {
1109 1032 if ( ! Actions::sync_allowed() ) {
1110 1033 WP_CLI::error( __( 'Jetpack sync is not currently allowed for this site.', 'jetpack' ) );
1111 1034 }
1112 1035
@@ -1114,13 +1037,12 @@
1114 1037 $action = isset( $args[1] ) ? $args[1] : 'peek';
1115 1038
1116 1039 // We map the queue name that way we can support more friendly queue names in the commands, but still use
1117 1040 // the queue name that the code expects.
1118 - $allowed_queues = array(
1041 + $queue_name_map = $allowed_queues = array(
1119 1042 'incremental' => 'sync',
1120 1043 'full' => 'full_sync',
1121 1044 );
1122 - $queue_name_map = $allowed_queues;
1123 1045 $mapped_queue_name = isset( $queue_name_map[ $queue_name ] ) ? $queue_name_map[ $queue_name ] : $queue_name;
1124 1046
1125 1047 switch ( $action ) {
1126 1048 case 'peek':
@@ -1134,9 +1056,9 @@
1134 1056 $collection = array();
1135 1057 foreach ( $items as $item ) {
1136 1058 $collection[] = array(
1137 1059 'action' => $item[0],
1138 - 'args' => wp_json_encode( $item[1] ),
1060 + 'args' => json_encode( $item[1] ),
1139 1061 'current_user_id' => $item[2],
1140 1062 'microtime' => $item[3],
1141 1063 'importing' => (string) $item[4],
1142 1064 );
@@ -1166,18 +1088,14 @@
1166 1088 * : JSON blob of WPCOM API token
1167 1089 * [--partner_tracking_id=<partner_tracking_id>]
1168 1090 * : This is an optional ID that a host can pass to help identify a site in logs on WordPress.com
1169 1091 *
1170 - * @synopsis <token_json> [--partner_tracking_id=<partner_tracking_id>]
1171 - *
1172 - * @param array $args Positional args.
1173 - * @param array $named_args Named args.
1092 + * * @synopsis <token_json> [--partner_tracking_id=<partner_tracking_id>]
1174 1093 */
1175 1094 public function partner_cancel( $args, $named_args ) {
1176 1095 list( $token_json ) = $args;
1177 1096
1178 - $token = $token_json ? json_decode( $token_json ) : null;
1179 - if ( ! $token ) {
1097 + if ( ! $token_json || ! ( $token = json_decode( $token_json ) ) ) {
1180 1098 /* translators: %s is the invalid JSON string */
1181 1099 $this->partner_provision_error( new WP_Error( 'missing_access_token', sprintf( __( 'Invalid token JSON: %s', 'jetpack' ), $token_json ) ) );
1182 1100 }
1183 1101
@@ -1188,9 +1106,9 @@
1188 1106 if ( ! isset( $token->access_token ) ) {
1189 1107 $this->partner_provision_error( new WP_Error( 'missing_access_token', __( 'Missing or invalid access token', 'jetpack' ) ) );
1190 1108 }
1191 1109
1192 - if ( Identity_Crisis::validate_sync_error_idc_option() ) {
1110 + if ( Jetpack::validate_sync_error_idc_option() ) {
1193 1111 $this->partner_provision_error(
1194 1112 new WP_Error(
1195 1113 'site_in_safe_mode',
1196 1114 esc_html__( 'Can not cancel a plan while in safe mode. See: https://jetpack.com/support/safe-mode/', 'jetpack' )
@@ -1220,8 +1138,10 @@
1220 1138 }
1221 1139
1222 1140 $result = Client::_wp_remote_request( $url, $request );
1223 1141
1142 + Jetpack_Options::delete_option( 'onboarding' );
1143 +
1224 1144 if ( is_wp_error( $result ) ) {
1225 1145 $this->partner_provision_error( $result );
1226 1146 }
1227 1147
@@ -1242,8 +1162,10 @@
1242 1162 * [--wpcom_user_id=<user_id>]
1243 1163 * : WordPress.com ID of user to connect as (must be whitelisted against partner key)
1244 1164 * [--wpcom_user_email=<wpcom_user_email>]
1245 1165 * : Override the email we send to WordPress.com for registration
1166 + * [--onboarding=<onboarding>]
1167 + * : Guide the user through an onboarding wizard
1246 1168 * [--force_register=<register>]
1247 1169 * : Whether to force a site to register
1248 1170 * [--force_connect=<force_connect>]
1249 1171 * : Force JPS to not reuse existing credentials
@@ -1258,18 +1180,14 @@
1258 1180 *
1259 1181 * $ wp jetpack partner_provision '{ some: "json" }' premium 1
1260 1182 * { success: true }
1261 1183 *
1262 - * @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>]
1263 - *
1264 - * @param array $args Positional args.
1265 - * @param array $named_args Named args.
1184 + * @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>]
1266 1185 */
1267 1186 public function partner_provision( $args, $named_args ) {
1268 1187 list( $token_json ) = $args;
1269 1188
1270 - $token = $token_json ? json_decode( $token_json ) : null;
1271 - if ( ! $token ) {
1189 + if ( ! $token_json || ! ( $token = json_decode( $token_json ) ) ) {
1272 1190 /* translators: %s is the invalid JSON string */
1273 1191 $this->partner_provision_error( new WP_Error( 'missing_access_token', sprintf( __( 'Invalid token JSON: %s', 'jetpack' ), $token_json ) ) );
1274 1192 }
1275 1193
@@ -1288,10 +1206,10 @@
1288 1206
1289 1207 $body_json = Jetpack_Provision::partner_provision( $token->access_token, $named_args );
1290 1208
1291 1209 if ( is_wp_error( $body_json ) ) {
1292 - WP_CLI::error(
1293 - wp_json_encode(
1210 + error_log(
1211 + json_encode(
1294 1212 array(
1295 1213 'success' => false,
1296 1214 'error_code' => $body_json->get_error_code(),
1297 1215 'error_message' => $body_json->get_error_message(),
@@ -1300,9 +1218,9 @@
1300 1218 );
1301 1219 exit( 1 );
1302 1220 }
1303 1221
1304 - WP_CLI::log( wp_json_encode( $body_json ) );
1222 + WP_CLI::log( json_encode( $body_json ) );
1305 1223 }
1306 1224
1307 1225 /**
1308 1226 * Manages your Jetpack sitemap
@@ -1317,14 +1235,11 @@
1317 1235 * wp jetpack sitemap rebuild
1318 1236 *
1319 1237 * @subcommand sitemap
1320 1238 * @synopsis <rebuild> [--purge]
1321 - *
1322 - * @param array $args Positional args.
1323 - * @param array $assoc_args Named args.
1324 1239 */
1325 1240 public function sitemap( $args, $assoc_args ) {
1326 - if ( ! Jetpack::is_connection_ready() ) {
1241 + if ( ! Jetpack::is_active() ) {
1327 1242 WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1328 1243 }
1329 1244 if ( ! Jetpack::is_module_active( 'sitemaps' ) ) {
1330 1245 WP_CLI::error( __( 'Jetpack Sitemaps module is not currently active. Activate it first if you want to work with sitemaps.', 'jetpack' ) );
@@ -1349,11 +1264,8 @@
1349 1264 *
1350 1265 * wp jetpack authorize_user --token=123456789abcdef
1351 1266 *
1352 1267 * @synopsis --token=<value>
1353 - *
1354 - * @param array $args Positional args.
1355 - * @param array $named_args Named args.
1356 1268 */
1357 1269 public function authorize_user( $args, $named_args ) {
1358 1270 if ( ! is_user_logged_in() ) {
1359 1271 WP_CLI::error( __( 'Please select a user to authorize via the --user global argument.', 'jetpack' ) );
@@ -1362,16 +1274,16 @@
1362 1274 if ( empty( $named_args['token'] ) ) {
1363 1275 WP_CLI::error( __( 'A non-empty token argument must be passed.', 'jetpack' ) );
1364 1276 }
1365 1277
1366 - $is_connection_owner = ! Jetpack::connection()->has_connected_owner();
1367 - $current_user_id = get_current_user_id();
1278 + $is_master_user = ! Jetpack::is_active();
1279 + $current_user_id = get_current_user_id();
1368 1280
1369 - ( new Tokens() )->update_user_token( $current_user_id, sprintf( '%s.%d', $named_args['token'], $current_user_id ), $is_connection_owner );
1281 + Connection_Utils::update_user_token( $current_user_id, sprintf( '%s.%d', $named_args['token'], $current_user_id ), $is_master_user );
1370 1282
1371 1283 WP_CLI::log( wp_json_encode( $named_args ) );
1372 1284
1373 - if ( $is_connection_owner ) {
1285 + if ( $is_master_user ) {
1374 1286 /**
1375 1287 * Auto-enable SSO module for new Jetpack Start connections
1376 1288 *
1377 1289 * @since 5.0.0
@@ -1419,14 +1331,11 @@
1419 1331 *
1420 1332 * ## EXAMPLES
1421 1333 *
1422 1334 * wp jetpack call_api --resource='/sites/%d'
1423 - *
1424 - * @param array $args Positional args.
1425 - * @param array $named_args Named args.
1426 1335 */
1427 1336 public function call_api( $args, $named_args ) {
1428 - if ( ! Jetpack::is_connection_ready() ) {
1337 + if ( ! Jetpack::is_active() ) {
1429 1338 WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1430 1339 }
1431 1340
1432 1341 $consumed_args = array(
@@ -1443,9 +1352,9 @@
1443 1352 $decoded_body = ! empty( $named_args['body'] )
1444 1353 ? json_decode( $named_args['body'], true )
1445 1354 : false;
1446 1355
1447 - $resource_url = ( ! str_contains( $named_args['resource'], '%d' ) )
1356 + $resource_url = ( false === strpos( $named_args['resource'], '%d' ) )
1448 1357 ? $named_args['resource']
1449 1358 : sprintf( $named_args['resource'], Jetpack_Options::get_option( 'id' ) );
1450 1359
1451 1360 $response = Client::wpcom_json_api_request_as_blog(
@@ -1521,14 +1430,11 @@
1521 1430 * ## EXAMPLES
1522 1431 *
1523 1432 * wp jetpack upload_ssh_creds --host=example.com --ssh-user=example --pass=password
1524 1433 * wp jetpack updload_ssh_creds --host=example.com --ssh-user=example --kpri=key
1525 - *
1526 - * @param array $args Positional args.
1527 - * @param array $named_args Named args.
1528 1434 */
1529 1435 public function upload_ssh_creds( $args, $named_args ) {
1530 - if ( ! Jetpack::is_connection_ready() ) {
1436 + if ( ! Jetpack::is_active() ) {
1531 1437 WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1532 1438 }
1533 1439
1534 1440 $required_args = array(
@@ -1613,11 +1519,8 @@
1613 1519 *
1614 1520 * ## EXAMPLES
1615 1521 *
1616 1522 * wp jetpack get_stats
1617 - *
1618 - * @param array $args Positional args.
1619 - * @param array $named_args Named args.
1620 1523 */
1621 1524 public function get_stats( $args, $named_args ) {
1622 1525 $selected_args = array_intersect_key(
1623 1526 $named_args,
@@ -1669,11 +1572,8 @@
1669 1572 *
1670 1573 * [<identifier>]
1671 1574 * : The connection ID or service to perform an action on.
1672 1575 *
1673 - * [--ignore-cache]
1674 - * : Whether to ignore connections cache.
1675 - *
1676 1576 * [--format=<format>]
1677 1577 * : Allows overriding the output of the command when listing connections.
1678 1578 * ---
1679 1579 * default: table
@@ -1690,19 +1590,16 @@
1690 1590 *
1691 1591 * # List all publicize connections.
1692 1592 * $ wp jetpack publicize list
1693 1593 *
1694 - * # List all publicize connections, ignoring the cache.
1695 - * $ wp jetpack publicize list --ignore-cache
1696 - *
1697 1594 * # List publicize connections for a given service.
1698 - * $ wp jetpack publicize list linkedin
1595 + * $ wp jetpack publicize list twitter
1699 1596 *
1700 1597 * # List all publicize connections for a given user.
1701 1598 * $ wp --user=1 jetpack publicize list
1702 1599 *
1703 1600 * # List all publicize connections for a given user and service.
1704 - * $ wp --user=1 jetpack publicize list linkedin
1601 + * $ wp --user=1 jetpack publicize list twitter
1705 1602 *
1706 1603 * # Display details for a given connection.
1707 1604 * $ wp jetpack publicize list 123456
1708 1605 *
@@ -1712,20 +1609,17 @@
1712 1609 * # Disconnect all connections.
1713 1610 * $ wp jetpack publicize disconnect all
1714 1611 *
1715 1612 * # Disconnect all connections for a given service.
1716 - * $ wp jetpack publicize disconnect linkedin
1717 - *
1718 - * @param array $args Positional args.
1719 - * @param array $named_args Named args.
1613 + * $ wp jetpack publicize disconnect twitter
1720 1614 */
1721 1615 public function publicize( $args, $named_args ) {
1722 - if ( ! Jetpack::connection()->has_connected_owner() ) {
1723 - WP_CLI::error( __( 'Jetpack Social requires a user-level connection to WordPress.com', 'jetpack' ) );
1616 + if ( ! Jetpack::is_active() ) {
1617 + WP_CLI::error( __( 'Jetpack is not currently connected to WordPress.com', 'jetpack' ) );
1724 1618 }
1725 1619
1726 1620 if ( ! Jetpack::is_module_active( 'publicize' ) ) {
1727 - WP_CLI::error( __( 'The Jetpack Social module is not active.', 'jetpack' ) );
1621 + WP_CLI::error( __( 'The publicize module is not active.', 'jetpack' ) );
1728 1622 }
1729 1623
1730 1624 if ( ( new Status() )->is_offline_mode() ) {
1731 1625 if (
@@ -1731,18 +1625,18 @@
1731 1625 if (
1732 1626 ! defined( 'JETPACK_DEV_DEBUG' ) &&
1733 1627 ! has_filter( 'jetpack_development_mode' ) &&
1734 1628 ! has_filter( 'jetpack_offline_mode' ) &&
1735 - ! str_contains( site_url(), '.' )
1629 + false === strpos( site_url(), '.' )
1736 1630 ) {
1737 - 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' ) );
1631 + 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 publicize module will not load.", 'jetpack' ) );
1738 1632 }
1739 1633
1740 - WP_CLI::error( __( 'Jetpack is currently in offline mode, so the Jetpack Social module will not load.', 'jetpack' ) );
1634 + WP_CLI::error( __( 'Jetpack is currently in offline mode, so the publicize module will not load.', 'jetpack' ) );
1741 1635 }
1742 1636
1743 - if ( ! class_exists( Publicize::class ) ) {
1744 - WP_CLI::error( __( 'The Jetpack Social module is not loaded.', 'jetpack' ) );
1637 + if ( ! class_exists( 'Publicize' ) ) {
1638 + WP_CLI::error( __( 'The publicize module is not loaded.', 'jetpack' ) );
1745 1639 }
1746 1640
1747 1641 $action = $args[0];
1748 1642 $publicize = new Publicize();
@@ -1751,23 +1645,30 @@
1751 1645 $id_is_service = in_array( $identifier, $services, true );
1752 1646
1753 1647 switch ( $action ) {
1754 1648 case 'list':
1755 - $_args = array(
1756 - 'ignore_cache' => $named_args['ignore-cache'] ?? false,
1757 - );
1649 + $connections_to_return = array();
1650 +
1758 1651 // For the CLI command, let's return all connections when a user isn't specified. This
1759 1652 // differs from the logic in the Publicize class.
1760 - $connections_to_return = is_user_logged_in()
1761 - ? Connections::get_all_for_user( $_args )
1762 - : Connections::get_all( $_args );
1653 + $option_connections = is_user_logged_in()
1654 + ? (array) $publicize->get_all_connections_for_user()
1655 + : (array) $publicize->get_all_connections();
1763 1656
1657 + foreach ( $option_connections as $service_name => $connections ) {
1658 + foreach ( (array) $connections as $id => $connection ) {
1659 + $connection['id'] = $id;
1660 + $connection['service'] = $service_name;
1661 + $connections_to_return[] = $connection;
1662 + }
1663 + }
1664 +
1764 1665 if ( $id_is_service && ! empty( $identifier ) && ! empty( $connections_to_return ) ) {
1765 1666 $temp_connections = $connections_to_return;
1766 1667 $connections_to_return = array();
1767 1668
1768 1669 foreach ( $temp_connections as $connection ) {
1769 - if ( $identifier === $connection['service_name'] ) {
1670 + if ( $identifier === $connection['service'] ) {
1770 1671 $connections_to_return[] = $connection;
1771 1672 }
1772 1673 }
1773 1674 }
@@ -1772,18 +1673,23 @@
1772 1673 }
1773 1674 }
1774 1675
1775 1676 if ( $identifier && ! $id_is_service && ! empty( $connections_to_return ) ) {
1776 - $connections_to_return = wp_list_filter( $connections_to_return, array( 'connection_id' => $identifier ) );
1677 + $connections_to_return = wp_list_filter( $connections_to_return, array( 'id' => $identifier ) );
1777 1678 }
1778 1679
1779 1680 $expected_keys = array(
1780 - 'connection_id',
1781 - 'service_name',
1782 - 'display_name',
1681 + 'id',
1682 + 'service',
1683 + 'user_id',
1684 + 'provider',
1685 + 'issued',
1686 + 'expires',
1783 1687 'external_id',
1784 - 'wpcom_user_id',
1785 - 'shared',
1688 + 'external_name',
1689 + 'external_display',
1690 + 'type',
1691 + 'connection_data',
1786 1692 );
1787 1693
1788 1694 // Somehow, a test site ended up in a state where $connections_to_return looked like:
1789 1695 // array( array( array( 'id' => 0, 'service' => 0 ) ) ) // phpcs:ignore Squiz.PHP.CommentedOutCode.Found
@@ -1813,27 +1719,35 @@
1813 1719 // If the connection ID is 'all' then delete all connections. If the connection ID
1814 1720 // matches a service, delete all connections for that service.
1815 1721 if ( 'all' === $identifier || $id_is_service ) {
1816 1722 if ( 'all' === $identifier ) {
1817 - WP_CLI::log( __( "You're about to delete all Jetpack Social connections.", 'jetpack' ) );
1723 + WP_CLI::log( __( "You're about to delete all publicize connections.", 'jetpack' ) );
1818 1724 } else {
1819 1725 /* translators: %s is a lowercase string for a social network. */
1820 - WP_CLI::log( sprintf( __( "You're about to delete all Jetpack Social connections to %s.", 'jetpack' ), $identifier ) );
1726 + WP_CLI::log( sprintf( __( "You're about to delete all publicize connections to %s.", 'jetpack' ), $identifier ) );
1821 1727 }
1822 1728
1823 1729 jetpack_cli_are_you_sure();
1824 1730
1731 + $connections = array();
1825 1732 $service = $identifier;
1826 - $connections = is_user_logged_in()
1827 - ? Connections::get_all_for_user()
1828 - : Connections::get_all();
1829 1733
1830 - if ( 'all' !== $service ) {
1831 - $connections = wp_list_filter( $connections, array( 'service_name' => $service ) );
1734 + $option_connections = is_user_logged_in()
1735 + ? (array) $publicize->get_all_connections_for_user()
1736 + : (array) $publicize->get_all_connections();
1737 +
1738 + if ( 'all' === $service ) {
1739 + foreach ( (array) $option_connections as $service_name => $service_connections ) {
1740 + foreach ( $service_connections as $id => $connection ) {
1741 + $connections[ $id ] = $connection;
1742 + }
1743 + }
1744 + } elseif ( ! empty( $option_connections[ $service ] ) ) {
1745 + $connections = $option_connections[ $service ];
1832 1746 }
1833 1747
1834 1748 if ( ! empty( $connections ) ) {
1835 - $count = is_countable( $connections ) ? count( $connections ) : 0;
1749 + $count = count( $connections );
1836 1750 $progress = \WP_CLI\Utils\make_progress_bar(
1837 1751 /* translators: %s is a lowercase string for a social network. */
1838 1752 sprintf( __( 'Disconnecting all connections to %s.', 'jetpack' ), $service ),
1839 1753 $count
@@ -1838,64 +1752,52 @@
1838 1752 sprintf( __( 'Disconnecting all connections to %s.', 'jetpack' ), $service ),
1839 1753 $count
1840 1754 );
1841 1755
1842 - foreach ( $connections as $connection ) {
1843 - $id = $connection['connection_id'];
1756 + foreach ( $connections as $id => $connection ) {
1844 1757 if ( false === $publicize->disconnect( false, $id ) ) {
1845 1758 WP_CLI::error(
1846 1759 sprintf(
1847 1760 /* translators: %1$d is a numeric ID and %2$s is a lowercase string for a social network. */
1848 - __( 'Jetpack Social connection %d could not be disconnected', 'jetpack' ),
1761 + __( 'Publicize connection %d could not be disconnected', 'jetpack' ),
1849 1762 $id
1850 1763 )
1851 1764 );
1852 1765 }
1853 1766
1854 - // @phan-suppress-next-line PhanUndeclaredClassMethod - Class is missing from php-stubs/wp-cli-stubs 🤷
1855 1767 $progress->tick();
1856 1768 }
1857 1769
1858 - // @phan-suppress-next-line PhanUndeclaredClassMethod - Class is missing from php-stubs/wp-cli-stubs 🤷
1859 1770 $progress->finish();
1860 1771
1861 1772 if ( 'all' === $service ) {
1862 - WP_CLI::success( __( 'All Jetpack Social connections were successfully disconnected.', 'jetpack' ) );
1773 + WP_CLI::success( __( 'All publicize connections were successfully disconnected.', 'jetpack' ) );
1863 1774 } else {
1864 1775 /* translators: %s is a lowercase string for a social network. */
1865 - WP_CLI::success( sprintf( __( 'All Jetpack Social connections to %s were successfully disconnected.', 'jetpack' ), $service ) );
1776 + WP_CLI::success( __( 'All publicize connections to %s were successfully disconnected.', 'jetpack' ), $service );
1866 1777 }
1867 1778 }
1868 - } elseif ( false !== $publicize->disconnect( false, $identifier ) ) {
1869 - /* translators: %d is a numeric ID. Example: 1234. */
1870 - WP_CLI::success( sprintf( __( 'Jetpack Social connection %d has been disconnected.', 'jetpack' ), $identifier ) );
1871 1779 } else {
1872 - /* translators: %d is a numeric ID. Example: 1234. */
1873 - WP_CLI::error( sprintf( __( 'Jetpack Social connection %d could not be disconnected.', 'jetpack' ), $identifier ) );
1780 + if ( false !== $publicize->disconnect( false, $identifier ) ) {
1781 + /* translators: %d is a numeric ID. Example: 1234. */
1782 + WP_CLI::success( sprintf( __( 'Publicize connection %d has been disconnected.', 'jetpack' ), $identifier ) );
1783 + } else {
1784 + /* translators: %d is a numeric ID. Example: 1234. */
1785 + WP_CLI::error( sprintf( __( 'Publicize connection %d could not be disconnected.', 'jetpack' ), $identifier ) );
1786 + }
1874 1787 }
1875 1788 break; // disconnect.
1876 1789 }
1877 1790 }
1878 1791
1879 - /**
1880 - * Get the API host.
1881 - *
1882 - * @return string URL.
1883 - */
1884 1792 private function get_api_host() {
1885 1793 $env_api_host = getenv( 'JETPACK_START_API_HOST', true );
1886 1794 return $env_api_host ? 'https://' . $env_api_host : JETPACK__WPCOM_JSON_API_BASE;
1887 1795 }
1888 1796
1889 - /**
1890 - * Log and exit on a partner provision error.
1891 - *
1892 - * @param WP_Error $error Error.
1893 - * @return never
1894 - */
1895 1797 private function partner_provision_error( $error ) {
1896 1798 WP_CLI::log(
1897 - wp_json_encode(
1799 + json_encode(
1898 1800 array(
1899 1801 'success' => false,
1900 1802 'error_code' => $error->get_error_code(),
1901 1803 'error_message' => $error->get_error_message(),
@@ -1953,21 +1855,19 @@
1953 1855 * @param array $args Positional parameters. Only one is used, that corresponds to the block title.
1954 1856 * @param array $assoc_args Associative parameters defined in the scaffold() method.
1955 1857 */
1956 1858 public function block( $args, $assoc_args ) {
1957 - if ( ! isset( $args[1] ) ) {
1859 + if ( isset( $args[1] ) ) {
1860 + $title = ucwords( $args[1] );
1861 + } else {
1958 1862 WP_CLI::error( esc_html__( 'The title parameter is required.', 'jetpack' ) . ' 👻' );
1959 1863 exit( 1 );
1960 1864 }
1961 1865
1962 - $title = ucwords( $args[1] );
1963 -
1964 1866 $slug = isset( $assoc_args['slug'] )
1965 1867 ? $assoc_args['slug']
1966 1868 : sanitize_title( $title );
1967 1869
1968 - $next_version = "\x24\x24next-version$$"; // Escapes to hide the string from tools/replace-next-version-tag.sh
1969 -
1970 1870 $variation_options = array( 'production', 'experimental', 'beta' );
1971 1871 $variation = ( isset( $assoc_args['variation'] ) && in_array( $assoc_args['variation'], $variation_options, true ) )
1972 1872 ? $assoc_args['variation']
1973 1873 : 'beta';
@@ -1994,40 +1894,43 @@
1994 1894 }
1995 1895
1996 1896 $wp_filesystem->mkdir( $path );
1997 1897
1998 - $keywords = isset( $assoc_args['keywords'] )
1999 - ? array_map(
2000 - function ( $keyword ) {
2001 - return trim( $keyword );
2002 - },
2003 - array_slice( explode( ',', $assoc_args['keywords'] ), 0, 3 )
2004 - )
2005 - : array();
1898 + $hasKeywords = isset( $assoc_args['keywords'] );
2006 1899
2007 1900 $files = array(
2008 - "$path/block.json" => self::render_block_file(
2009 - 'block-block-json',
1901 + "$path/$slug.php" => $this->render_block_file(
1902 + 'block-register-php',
2010 1903 array(
2011 - 'slug' => $slug,
2012 - 'title' => wp_json_encode( $title, JSON_UNESCAPED_UNICODE ),
2013 - 'description' => isset( $assoc_args['description'] )
2014 - ? wp_json_encode( $assoc_args['description'], JSON_UNESCAPED_UNICODE )
2015 - : wp_json_encode( $title, JSON_UNESCAPED_UNICODE ),
2016 - 'nextVersion' => $next_version,
2017 - 'keywords' => wp_json_encode( $keywords, JSON_UNESCAPED_UNICODE ),
1904 + 'slug' => $slug,
1905 + 'title' => $title,
1906 + 'underscoredSlug' => str_replace( '-', '_', $slug ),
1907 + 'underscoredTitle' => str_replace( ' ', '_', $title ),
1908 + 'jetpackVersion' => substr( JETPACK__VERSION, 0, strpos( JETPACK__VERSION, '.' ) ) . '.x',
2018 1909 )
2019 1910 ),
2020 - "$path/$slug.php" => self::render_block_file(
2021 - 'block-register-php',
1911 + "$path/index.js" => $this->render_block_file(
1912 + 'block-index-js',
2022 1913 array(
2023 - 'nextVersion' => $next_version,
2024 - 'title' => $title,
2025 - 'underscoredTitle' => str_replace( ' ', '_', $title ),
1914 + 'slug' => $slug,
1915 + 'title' => $title,
1916 + 'description' => isset( $assoc_args['description'] )
1917 + ? $assoc_args['description']
1918 + : $title,
1919 + 'keywords' => $hasKeywords
1920 + ? array_map(
1921 + function( $keyword ) {
1922 + // Construction necessary for Mustache lists
1923 + return array( 'keyword' => trim( $keyword ) );
1924 + },
1925 + explode( ',', $assoc_args['keywords'], 3 )
1926 + )
1927 + : '',
1928 + 'hasKeywords' => $hasKeywords,
2026 1929 )
2027 1930 ),
2028 - "$path/editor.js" => self::render_block_file( 'block-editor-js' ),
2029 - "$path/editor.scss" => self::render_block_file(
1931 + "$path/editor.js" => $this->render_block_file( 'block-editor-js' ),
1932 + "$path/editor.scss" => $this->render_block_file(
2030 1933 'block-editor-scss',
2031 1934 array(
2032 1935 'slug' => $slug,
2033 1936 'title' => $title,
@@ -2032,9 +1935,9 @@
2032 1935 'slug' => $slug,
2033 1936 'title' => $title,
2034 1937 )
2035 1938 ),
2036 - "$path/edit.js" => self::render_block_file(
1939 + "$path/edit.js" => $this->render_block_file(
2037 1940 'block-edit-js',
2038 1941 array(
2039 1942 'title' => $title,
2040 1943 'className' => str_replace( ' ', '', ucwords( str_replace( '-', ' ', $slug ) ) ),
@@ -2039,8 +1942,10 @@
2039 1942 'title' => $title,
2040 1943 'className' => str_replace( ' ', '', ucwords( str_replace( '-', ' ', $slug ) ) ),
2041 1944 )
2042 1945 ),
1946 + "$path/icon.js" => $this->render_block_file( 'block-icon-js' ),
1947 + "$path/attributes.js" => $this->render_block_file( 'block-attributes-js' ),
2043 1948 );
2044 1949
2045 1950 $files_written = array();
2046 1951
@@ -2086,10 +1991,10 @@
2086 1991
2087 1992 if ( 'beta' === $variation || 'experimental' === $variation ) {
2088 1993 $block_constant = sprintf(
2089 1994 /* translators: the placeholder is a constant name */
2090 - esc_html__( 'To load the block, add the constant JETPACK_BLOCKS_VARIATION set to %1$s to your wp-config.php file', 'jetpack' ),
2091 - $variation
1995 + esc_html__( 'To load the block, add the constant %1$s as true to your wp-config.php file', 'jetpack' ),
1996 + ( 'beta' === $variation ? 'JETPACK_BETA_BLOCKS' : 'JETPACK_EXPERIMENTAL_BLOCKS' )
2092 1997 );
2093 1998 } else {
2094 1999 $block_constant = '';
2095 2000 }
@@ -2100,9 +2005,9 @@
2100 2005 esc_html__( 'Successfully created block %1$s with slug %2$s', 'jetpack' ) . ' 🎉' . "\n" .
2101 2006 "--------------------------------------------------------------------------------------------------------------------\n" .
2102 2007 /* translators: the placeholder is a directory path */
2103 2008 esc_html__( 'The files were created at %3$s', 'jetpack' ) . "\n" .
2104 - esc_html__( 'To start using the block, build the blocks with pnpm run build-extensions', 'jetpack' ) . "\n" .
2009 + esc_html__( 'To start using the block, build the blocks with yarn run build-extensions', 'jetpack' ) . "\n" .
2105 2010 /* translators: the placeholder is a file path */
2106 2011 esc_html__( 'The block slug has been added to the %4$s list at %5$s', 'jetpack' ) . "\n" .
2107 2012 '%6$s' . "\n" .
2108 2013 /* translators: the placeholder is a URL */
@@ -2112,9 +2017,9 @@
2112 2017 $path,
2113 2018 $variation,
2114 2019 $block_list_path,
2115 2020 $block_constant,
2116 - 'https://github.com/Automattic/jetpack/blob/trunk/projects/plugins/jetpack/extensions/README.md#developing-block-editor-extensions-in-jetpack'
2021 + 'https://github.com/Automattic/jetpack/blob/master/extensions/README.md#develop-new-blocks'
2117 2022 ) . '--------------------------------------------------------------------------------------------------------------------'
2118 2023 );
2119 2024 }
2120 2025 }
@@ -2121,10 +2026,11 @@
2121 2026
2122 2027 /**
2123 2028 * Built the file replacing the placeholders in the template with the data supplied.
2124 2029 *
2125 - * @param string $template Template.
2126 - * @param array $data Data.
2030 + * @param string $template
2031 + * @param array $data
2032 + *
2127 2033 * @return string mixed
2128 2034 */
2129 2035 private static function render_block_file( $template, $data = array() ) {
2130 2036 return \WP_CLI\Utils\mustache_render( JETPACK__PLUGIN_DIR . "wp-cli-templates/$template.mustache", $data );
@@ -2130,23 +2036,21 @@
2130 2036 return \WP_CLI\Utils\mustache_render( JETPACK__PLUGIN_DIR . "wp-cli-templates/$template.mustache", $data );
2131 2037 }
2132 2038 }
2133 2039
2134 -// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move these functions to some other file.
2135 -
2136 -/**
2040 +/*
2137 2041 * Standard "ask for permission to continue" function.
2138 2042 * If action cancelled, ask if they need help.
2139 2043 *
2140 2044 * Written outside of the class so it's not listed as an executable command w/ 'wp jetpack'
2141 2045 *
2142 - * @param bool $flagged false = normal option | true = flagged by get_jetpack_options_for_reset().
2143 - * @param string $error_msg Error message.
2046 + * @param $flagged bool false = normal option | true = flagged by get_jetpack_options_for_reset()
2047 + * @param $error_msg string (optional)
2144 2048 */
2145 2049 function jetpack_cli_are_you_sure( $flagged = false, $error_msg = false ) {
2146 2050 $cli = new Jetpack_CLI();
2147 2051
2148 - // Default cancellation message.
2052 + // Default cancellation message
2149 2053 if ( ! $error_msg ) {
2150 2054 $error_msg =
2151 2055 __( 'Action cancelled. Have a question?', 'jetpack' )
2152 2056 . ' '
@@ -2157,14 +2061,14 @@
2157 2061
2158 2062 if ( ! $flagged ) {
2159 2063 $prompt_message = _x( 'Are you sure? This cannot be undone. Type "yes" to continue:', '"yes" is a command - do not translate.', 'jetpack' );
2160 2064 } else {
2161 - $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' );
2065 + $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' );
2162 2066 }
2163 2067
2164 2068 WP_CLI::line( $prompt_message );
2165 2069 $handle = fopen( 'php://stdin', 'r' );
2166 2070 $line = fgets( $handle );
2167 - if ( 'yes' !== trim( $line ) ) {
2071 + if ( 'yes' != trim( $line ) ) {
2168 2072 WP_CLI::error( $error_msg );
2169 2073 }
2170 2074 }