summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-plugin-storage.php')
-rw-r--r--plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-plugin-storage.php269
1 files changed, 269 insertions, 0 deletions
diff --git a/plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-plugin-storage.php b/plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-plugin-storage.php
new file mode 100644
index 00000000..8bf1884f
--- /dev/null
+++ b/plugins/jetpack/jetpack_vendor/automattic/jetpack-connection/src/class-plugin-storage.php
@@ -0,0 +1,269 @@
+<?php
+/**
+ * Storage for plugin connection information.
+ *
+ * @package automattic/jetpack-connection
+ */
+
+namespace Automattic\Jetpack\Connection;
+
+use WP_Error;
+
+/**
+ * The class serves a single purpose - to store the data which plugins use the connection, along with some auxiliary information.
+ */
+class Plugin_Storage {
+
+ const ACTIVE_PLUGINS_OPTION_NAME = 'jetpack_connection_active_plugins';
+
+ const PLUGINS_DISABLED_OPTION_NAME = 'jetpack_connection_disabled_plugins';
+
+ /**
+ * Whether this class was configured for the first time or not.
+ *
+ * @var boolean
+ */
+ private static $configured = false;
+
+ /**
+ * Refresh list of connected plugins upon intialization.
+ *
+ * @var boolean
+ */
+ private static $refresh_connected_plugins = false;
+
+ /**
+ * Connected plugins.
+ *
+ * @var array
+ */
+ private static $plugins = array();
+
+ /**
+ * The blog ID the storage is setup for.
+ * The data will be refreshed if the blog ID changes.
+ * Used for the multisite networks.
+ *
+ * @var int
+ */
+ private static $current_blog_id = null;
+
+ /**
+ * Add or update the plugin information in the storage.
+ *
+ * @param string $slug Plugin slug.
+ * @param array $args Plugin arguments, optional.
+ *
+ * @return bool
+ */
+ public static function upsert( $slug, array $args = array() ) {
+ self::$plugins[ $slug ] = $args;
+
+ // if plugin is not in the list of active plugins, refresh the list.
+ if ( ! array_key_exists( $slug, (array) get_option( self::ACTIVE_PLUGINS_OPTION_NAME, array() ) ) ) {
+ self::$refresh_connected_plugins = true;
+ }
+
+ return true;
+ }
+
+ /**
+ * Retrieve the plugin information by slug.
+ * WARNING: the method cannot be called until Plugin_Storage::configure is called, which happens on plugins_loaded
+ * Even if you don't use Jetpack Config, it may be introduced later by other plugins,
+ * so please make sure not to run the method too early in the code.
+ *
+ * @param string $slug The plugin slug.
+ *
+ * @return array|null|WP_Error
+ */
+ public static function get_one( $slug ) {
+ $plugins = self::get_all();
+
+ if ( $plugins instanceof WP_Error ) {
+ return $plugins;
+ }
+
+ return empty( $plugins[ $slug ] ) ? null : $plugins[ $slug ];
+ }
+
+ /**
+ * Retrieve info for all plugins that use the connection.
+ * WARNING: the method cannot be called until Plugin_Storage::configure is called, which happens on plugins_loaded
+ * Even if you don't use Jetpack Config, it may be introduced later by other plugins,
+ * so please make sure not to run the method too early in the code.
+ *
+ * @param bool $connected_only Exclude plugins that were explicitly disconnected.
+ *
+ * @return array|WP_Error
+ */
+ public static function get_all( $connected_only = false ) {
+ $maybe_error = self::ensure_configured();
+
+ if ( $maybe_error instanceof WP_Error ) {
+ return $maybe_error;
+ }
+
+ return $connected_only ? array_diff_key( self::$plugins, array_flip( self::get_all_disabled_plugins() ) ) : self::$plugins;
+ }
+
+ /**
+ * Remove the plugin connection info from Jetpack.
+ * WARNING: the method cannot be called until Plugin_Storage::configure is called, which happens on plugins_loaded
+ * Even if you don't use Jetpack Config, it may be introduced later by other plugins,
+ * so please make sure not to run the method too early in the code.
+ *
+ * @param string $slug The plugin slug.
+ *
+ * @return bool|WP_Error
+ */
+ public static function delete( $slug ) {
+ $maybe_error = self::ensure_configured();
+
+ if ( $maybe_error instanceof WP_Error ) {
+ return $maybe_error;
+ }
+
+ if ( array_key_exists( $slug, self::$plugins ) ) {
+ unset( self::$plugins[ $slug ] );
+ }
+
+ return true;
+ }
+
+ /**
+ * The method makes sure that `Jetpack\Config` has finished, and it's now safe to retrieve the list of plugins.
+ *
+ * @return bool|WP_Error
+ */
+ private static function ensure_configured() {
+ if ( ! self::$configured ) {
+ return new WP_Error( 'too_early', __( 'You cannot call this method until Jetpack Config is configured', 'jetpack-connection' ) );
+ }
+
+ if ( is_multisite() && get_current_blog_id() !== self::$current_blog_id ) {
+ self::$plugins = (array) get_option( self::ACTIVE_PLUGINS_OPTION_NAME, array() );
+ self::$current_blog_id = get_current_blog_id();
+ }
+
+ return true;
+ }
+
+ /**
+ * Called once to configure this class after plugins_loaded.
+ *
+ * @return void
+ */
+ public static function configure() {
+ if ( self::$configured ) {
+ return;
+ }
+
+ if ( is_multisite() ) {
+ self::$current_blog_id = get_current_blog_id();
+ }
+
+ // If a plugin was activated or deactivated.
+ $number_of_plugins_differ = count( self::$plugins ) !== count( (array) get_option( self::ACTIVE_PLUGINS_OPTION_NAME, array() ) );
+
+ if ( $number_of_plugins_differ || true === self::$refresh_connected_plugins ) {
+ self::update_active_plugins_option();
+ }
+
+ self::$configured = true;
+
+ }
+
+ /**
+ * Updates the active plugins option with current list of active plugins.
+ *
+ * @return void
+ */
+ 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();
+ }
+ }
+
+ /**
+ * Add the plugin to the set of disconnected ones.
+ *
+ * @param string $slug Plugin slug.
+ *
+ * @return bool
+ */
+ public static function disable_plugin( $slug ) {
+ $disconnects = self::get_all_disabled_plugins();
+
+ if ( ! in_array( $slug, $disconnects, true ) ) {
+ $disconnects[] = $slug;
+ update_option( self::PLUGINS_DISABLED_OPTION_NAME, $disconnects );
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove the plugin from the set of disconnected ones.
+ *
+ * @param string $slug Plugin slug.
+ *
+ * @return bool
+ */
+ public static function enable_plugin( $slug ) {
+ $disconnects = self::get_all_disabled_plugins();
+
+ $slug_index = array_search( $slug, $disconnects, true );
+ if ( false !== $slug_index ) {
+ unset( $disconnects[ $slug_index ] );
+ update_option( self::PLUGINS_DISABLED_OPTION_NAME, $disconnects );
+ }
+
+ return true;
+ }
+
+ /**
+ * Get all plugins that were disconnected by user.
+ *
+ * @return array
+ */
+ 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'
+ );
+ }
+}