PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-connection / src / class-plugin-storage.php
jetpack / jetpack_vendor / automattic / jetpack-connection / src Last commit date
abilities 4 days ago connectors 4 days ago health 4 days ago identity-crisis 1 month ago sso 1 month ago traits 9 months ago webhooks 9 months ago class-authorize-json-api.php 1 month ago class-client.php 4 days ago class-connection-assets.php 1 year ago class-connection-notice.php 8 months ago class-error-handler.php 4 days ago class-external-storage.php 4 months ago class-heartbeat.php 1 month ago class-initial-state.php 4 weeks ago class-manager.php 4 days ago class-nonce-handler.php 9 months ago class-package-version-tracker.php 1 month ago class-package-version.php 4 days ago class-partner-coupon.php 2 months ago class-partner.php 2 years ago class-plugin-storage.php 8 months ago class-plugin.php 9 months ago class-rest-authentication.php 4 days ago class-rest-connector.php 4 days ago class-secrets.php 9 months ago class-server-sandbox.php 2 months ago class-site-health.php 4 days ago class-terms-of-service.php 4 days ago class-tokens-locks.php 9 months ago class-tokens.php 4 days ago class-tracking.php 4 days ago class-urls.php 6 months ago class-user-account-status.php 4 days ago class-users-connection-admin.php 2 months ago class-utils.php 2 years ago class-webhooks.php 1 month ago class-xmlrpc-async-call.php 2 years ago class-xmlrpc-connector.php 9 months ago interface-manager.php 4 years ago interface-storage-provider.php 6 months ago
class-plugin-storage.php
262 lines
1 <?php
2 /**
3 * Storage for plugin connection information.
4 *
5 * @package automattic/jetpack-connection
6 */
7
8 namespace Automattic\Jetpack\Connection;
9
10 use Jetpack_Options;
11 use WP_Error;
12
13 /**
14 * The class serves a single purpose - to store the data which plugins use the connection, along with some auxiliary information.
15 */
16 class Plugin_Storage {
17
18 const ACTIVE_PLUGINS_OPTION_NAME = 'jetpack_connection_active_plugins';
19
20 /**
21 * Transient name used as flag to indicate that the active connected plugins list needs refreshing.
22 */
23 const ACTIVE_PLUGINS_REFRESH_FLAG = 'jetpack_connection_active_plugins_refresh';
24
25 /**
26 * Whether this class was configured for the first time or not.
27 *
28 * @var boolean
29 */
30 private static $configured = false;
31
32 /**
33 * Connected plugins.
34 *
35 * @var array
36 */
37 private static $plugins = array();
38
39 /**
40 * The blog ID the storage is setup for.
41 * The data will be refreshed if the blog ID changes.
42 * Used for the multisite networks.
43 *
44 * @var int
45 */
46 private static $current_blog_id = null;
47
48 /**
49 * Add or update the plugin information in the storage.
50 *
51 * @param string $slug Plugin slug.
52 * @param array $args Plugin arguments, optional.
53 *
54 * @return bool
55 */
56 public static function upsert( $slug, array $args = array() ) {
57 self::$plugins[ $slug ] = $args;
58
59 return true;
60 }
61
62 /**
63 * Retrieve the plugin information by slug.
64 * WARNING: the method cannot be called until Plugin_Storage::configure is called, which happens on plugins_loaded
65 * Even if you don't use Jetpack Config, it may be introduced later by other plugins,
66 * so please make sure not to run the method too early in the code.
67 *
68 * @param string $slug The plugin slug.
69 *
70 * @return array|null|WP_Error
71 */
72 public static function get_one( $slug ) {
73 $plugins = self::get_all();
74
75 if ( $plugins instanceof WP_Error ) {
76 return $plugins;
77 }
78
79 return empty( $plugins[ $slug ] ) ? null : $plugins[ $slug ];
80 }
81
82 /**
83 * Retrieve info for all plugins that use the connection.
84 * WARNING: the method cannot be called until Plugin_Storage::configure is called, which happens on plugins_loaded
85 * Even if you don't use Jetpack Config, it may be introduced later by other plugins,
86 * so please make sure not to run the method too early in the code.
87 *
88 * @return array|WP_Error
89 */
90 public static function get_all() {
91 $maybe_error = self::ensure_configured();
92
93 if ( $maybe_error instanceof WP_Error ) {
94 return $maybe_error;
95 }
96
97 return self::$plugins;
98 }
99
100 /**
101 * Remove the plugin connection info from Jetpack.
102 * WARNING: the method cannot be called until Plugin_Storage::configure is called, which happens on plugins_loaded
103 * Even if you don't use Jetpack Config, it may be introduced later by other plugins,
104 * so please make sure not to run the method too early in the code.
105 *
106 * @param string $slug The plugin slug.
107 *
108 * @return bool|WP_Error
109 */
110 public static function delete( $slug ) {
111 $maybe_error = self::ensure_configured();
112
113 if ( $maybe_error instanceof WP_Error ) {
114 return $maybe_error;
115 }
116
117 if ( array_key_exists( $slug, self::$plugins ) ) {
118 unset( self::$plugins[ $slug ] );
119 }
120
121 return true;
122 }
123
124 /**
125 * The method makes sure that `Jetpack\Config` has finished, and it's now safe to retrieve the list of plugins.
126 *
127 * @return bool|WP_Error
128 */
129 private static function ensure_configured() {
130 if ( ! self::$configured ) {
131 return new WP_Error( 'too_early', __( 'You cannot call this method until Jetpack Config is configured', 'jetpack-connection' ) );
132 }
133
134 if ( is_multisite() && get_current_blog_id() !== self::$current_blog_id ) {
135 if ( self::$current_blog_id ) {
136 // If blog ID got changed, pull the list of active plugins for that blog from the database.
137 self::$plugins = (array) get_option( self::ACTIVE_PLUGINS_OPTION_NAME, array() );
138 }
139 self::$current_blog_id = get_current_blog_id();
140 }
141
142 return true;
143 }
144
145 /**
146 * Called once to configure this class after plugins_loaded.
147 *
148 * @return void
149 */
150 public static function configure() {
151 if ( self::$configured ) {
152 return;
153 }
154
155 self::$configured = true;
156
157 add_action( 'update_option_active_plugins', array( __CLASS__, 'set_flag_to_refresh_active_connected_plugins' ) );
158
159 self::maybe_update_active_connected_plugins();
160 }
161
162 /**
163 * Set a flag to indicate that the active connected plugins list needs to be updated.
164 * This will happen when the `active_plugins` option is updated.
165 *
166 * @see configure
167 */
168 public static function set_flag_to_refresh_active_connected_plugins() {
169 set_transient( self::ACTIVE_PLUGINS_REFRESH_FLAG, time() );
170 }
171
172 /**
173 * Determine if we need to update the active connected plugins list.
174 */
175 public static function maybe_update_active_connected_plugins() {
176 $maybe_error = self::ensure_configured();
177
178 if ( $maybe_error instanceof WP_Error ) {
179 return;
180 }
181 // Only attempt to update the option if the corresponding flag is set.
182 if ( ! get_transient( self::ACTIVE_PLUGINS_REFRESH_FLAG ) ) {
183 return;
184 }
185 // Only attempt to update the option on POST requests.
186 // This will prevent the option from being updated multiple times due to concurrent requests.
187 if ( ! ( isset( $_SERVER['REQUEST_METHOD'] ) && 'POST' === $_SERVER['REQUEST_METHOD'] ) ) {
188 return;
189 }
190
191 delete_transient( self::ACTIVE_PLUGINS_REFRESH_FLAG );
192
193 if ( is_multisite() ) {
194 self::$current_blog_id = get_current_blog_id();
195 }
196
197 // If a plugin was activated or deactivated.
198 // self::$plugins is populated in Config::ensure_options_connection().
199 $configured_plugin_keys = array_keys( self::$plugins );
200 $stored_plugin_keys = array_keys( (array) get_option( self::ACTIVE_PLUGINS_OPTION_NAME, array() ) );
201 sort( $configured_plugin_keys );
202 sort( $stored_plugin_keys );
203
204 if ( $configured_plugin_keys !== $stored_plugin_keys ) {
205 self::update_active_plugins_option();
206 }
207 }
208
209 /**
210 * Updates the active plugins option with current list of active plugins.
211 *
212 * @return void
213 */
214 public static function update_active_plugins_option() {
215 // Note: Since this option is synced to wpcom, if you change its structure, you have to update the sanitizer at wpcom side.
216 update_option( self::ACTIVE_PLUGINS_OPTION_NAME, self::$plugins );
217 if ( ! class_exists( 'Automattic\Jetpack\Sync\Settings' ) || ! \Automattic\Jetpack\Sync\Settings::is_sync_enabled() ) {
218 self::update_active_plugins_wpcom_no_sync_fallback();
219 // Remove the checksum for active plugins, so it gets recalculated when sync gets activated.
220 $jetpack_callables_sync_checksum = Jetpack_Options::get_raw_option( 'jetpack_callables_sync_checksum' );
221 if ( isset( $jetpack_callables_sync_checksum['jetpack_connection_active_plugins'] ) ) {
222 unset( $jetpack_callables_sync_checksum['jetpack_connection_active_plugins'] );
223 Jetpack_Options::update_raw_option( 'jetpack_callables_sync_checksum', $jetpack_callables_sync_checksum );
224 }
225 }
226 }
227
228 /**
229 * Update active plugins option with current list of active plugins on WPCOM.
230 * This is a fallback to ensure this option is always up to date on WPCOM in case
231 * Sync is not present or disabled.
232 *
233 * @since 1.34.0
234 */
235 private static function update_active_plugins_wpcom_no_sync_fallback() {
236 $connection = new Manager();
237 if ( ! $connection->is_connected() ) {
238 return;
239 }
240
241 $site_id = \Jetpack_Options::get_option( 'id' );
242
243 $body = wp_json_encode(
244 array(
245 'active_connected_plugins' => self::$plugins,
246 ),
247 JSON_UNESCAPED_SLASHES
248 );
249
250 Client::wpcom_json_api_request_as_blog(
251 sprintf( '/sites/%d/jetpack-active-connected-plugins', $site_id ),
252 '2',
253 array(
254 'headers' => array( 'content-type' => 'application/json' ),
255 'method' => 'POST',
256 ),
257 $body,
258 'wpcom'
259 );
260 }
261 }
262