Skip to content

Commit

Permalink
Jetpack Connection: Add jetpack_connection_active_plugins fallback wh…
Browse files Browse the repository at this point in the history
…en Sync is not present (#22197)

* Jetpack Connection: Add fallback when Sync is not present

* Connection: Add changelog

* Add the active connected plugins list to the register request body.

Co-authored-by: Kim Brown <50059399+kbrown9@users.noreply.github.com>

Committed via a GitHub action: https://github.com/Automattic/jetpack/actions/runs/1652785980
  • Loading branch information
fgiannar authored and matticbot committed Jan 4, 2022
1 parent b1c0e72 commit fa09174
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 17 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

This is an alpha version! The changes listed here are not final.

### Added
- Jetpack Connection: Added fallback for keeping `jetpack_connection_active_plugins` consistent on WPCOM when Sync is not present.

### Changed
- Switch to pcov for code coverage.
- Updated package textdomain from `jetpack` to `jetpack-connection`.
Expand Down
37 changes: 20 additions & 17 deletions src/class-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -1065,6 +1065,8 @@ public function register( $api_endpoint = 'register' ) {
/* This action is documented in src/class-package-version-tracker.php */
$package_versions = apply_filters( 'jetpack_package_versions', array() );

$active_plugins_using_connection = Plugin_Storage::get_all();

/**
* Filters the request body for additional property addition.
*
Expand All @@ -1078,23 +1080,24 @@ public function register( $api_endpoint = 'register' ) {
'jetpack_register_request_body',
array_merge(
array(
'siteurl' => Urls::site_url(),
'home' => Urls::home_url(),
'gmt_offset' => $gmt_offset,
'timezone_string' => (string) get_option( 'timezone_string' ),
'site_name' => (string) get_option( 'blogname' ),
'secret_1' => $secrets['secret_1'],
'secret_2' => $secrets['secret_2'],
'site_lang' => get_locale(),
'timeout' => $timeout,
'stats_id' => $stats_id,
'state' => get_current_user_id(),
'site_created' => $this->get_assumed_site_creation_date(),
'jetpack_version' => Constants::get_constant( 'JETPACK__VERSION' ),
'ABSPATH' => Constants::get_constant( 'ABSPATH' ),
'current_user_email' => wp_get_current_user()->user_email,
'connect_plugin' => $this->get_plugin() ? $this->get_plugin()->get_slug() : null,
'package_versions' => $package_versions,
'siteurl' => Urls::site_url(),
'home' => Urls::home_url(),
'gmt_offset' => $gmt_offset,
'timezone_string' => (string) get_option( 'timezone_string' ),
'site_name' => (string) get_option( 'blogname' ),
'secret_1' => $secrets['secret_1'],
'secret_2' => $secrets['secret_2'],
'site_lang' => get_locale(),
'timeout' => $timeout,
'stats_id' => $stats_id,
'state' => get_current_user_id(),
'site_created' => $this->get_assumed_site_creation_date(),
'jetpack_version' => Constants::get_constant( 'JETPACK__VERSION' ),
'ABSPATH' => Constants::get_constant( 'ABSPATH' ),
'current_user_email' => wp_get_current_user()->user_email,
'connect_plugin' => $this->get_plugin() ? $this->get_plugin()->get_slug() : null,
'package_versions' => $package_versions,
'active_connected_plugins' => $active_plugins_using_connection,
),
self::$extra_register_params
)
Expand Down
36 changes: 36 additions & 0 deletions src/class-plugin-storage.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ public static function configure() {
public static function update_active_plugins_option() {
// Note: Since this options is synced to wpcom, if you change its structure, you have to update the sanitizer at wpcom side.
update_option( self::ACTIVE_PLUGINS_OPTION_NAME, self::$plugins );

if ( ! class_exists( 'Automattic\Jetpack\Sync\Settings' ) || ! \Automattic\Jetpack\Sync\Settings::is_sync_enabled() ) {
self::update_active_plugins_wpcom_no_sync_fallback();
}
}

/**
Expand Down Expand Up @@ -230,4 +234,36 @@ public static function get_all_disabled_plugins() {
return (array) get_option( self::PLUGINS_DISABLED_OPTION_NAME, array() );
}

/**
* Update active plugins option with current list of active plugins on WPCOM.
* This is a fallback to ensure this option is always up to date on WPCOM in case
* Sync is not present or disabled.
*
* @since $$next_version$$
*/
private static function update_active_plugins_wpcom_no_sync_fallback() {
$connection = new Manager();
if ( ! $connection->is_connected() ) {
return;
}

$site_id = \Jetpack_Options::get_option( 'id' );

$body = wp_json_encode(
array(
'active_connected_plugins' => self::$plugins,
)
);

Client::wpcom_json_api_request_as_blog(
sprintf( '/sites/%d/jetpack-active-connected-plugins', $site_id ),
'2',
array(
'headers' => array( 'content-type' => 'application/json' ),
'method' => 'POST',
),
$body,
'wpcom'
);
}
}
93 changes: 93 additions & 0 deletions tests/php/test_plugin_storage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
/**
* Unit tests for the Connection Plugin Storage class.
*
* @package automattic/jetpack-connection
* @see \Automattic\Jetpack\Connection\Plugin_Storage
*/

namespace Automattic\Jetpack\Connection;

use Automattic\Jetpack\Constants;
use PHPUnit\Framework\TestCase;
use WorDBless\Options as WorDBless_Options;

/**
* Unit tests for the Connection Plugin Storage class.
*
* @see \Automattic\Jetpack\Connection\Plugin_Storage
*/
class Test_Plugin_Storage extends TestCase {

/**
* Whether an http request to the jetpack-active-connected-plugins endoint was attempted.
*
* @var bool
*/
private $http_request_attempted = false;

/**
* Setting up the testing environment.
*
* @before
*/
public function set_up() {
Constants::set_constant( 'JETPACK__WPCOM_JSON_API_BASE', 'https://public-api.wordpress.com' );
}

/**
* Returning the environment into its initial state.
*
* @after
*/
public function tear_down() {
$this->http_request_attempted = false;
Constants::clear_constants();
WorDBless_Options::init()->clear_options();
}

/**
* Unit test for the `Plugin_Storage::update_active_plugins_option()` method.
*
* @covers Automattic\Jetpack\Connection\Plugin_Storage::update_active_plugins_option
*/
public function test_update_active_plugins_option_without_sync_will_trigger_fallback() {
\Jetpack_Options::update_option( 'blog_token', 'asdasd.123123' );
\Jetpack_Options::update_option( 'id', 1234 );

add_filter( 'pre_http_request', array( $this, 'intercept_remote_request' ), 10, 3 );
Plugin_Storage::update_active_plugins_option();
remove_filter( 'pre_http_request', array( $this, 'intercept_remote_request' ), 10 );
$this->assertTrue( $this->http_request_attempted );
}

/**
* Unit test for the `Plugin_Storage::update_active_plugins_option()` method.
*
* @covers Automattic\Jetpack\Connection\Plugin_Storage::update_active_plugins_option
*/
public function test_update_active_plugins_option_without_sync_fallback_will_return_early_if_not_connected() {
add_filter( 'pre_http_request', array( $this, 'intercept_remote_request' ), 10, 3 );
Plugin_Storage::update_active_plugins_option();
remove_filter( 'pre_http_request', array( $this, 'intercept_remote_request' ), 10 );
$this->assertFalse( $this->http_request_attempted );
}

/**
* Intercept remote HTTP request to WP.com, and mock the response.
* Should be hooked on the `pre_http_request` filter.
*
* @param false $preempt A preemptive return value of an HTTP request.
* @param array $args The request arguments.
* @param string $url The request URL.
*
* @return array
*/
public function intercept_remote_request( $preempt, $args, $url ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
$this->http_request_attempted = true;

return array(
'success' => true,
);
}
}

0 comments on commit fa09174

Please sign in to comment.