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