PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
← All changes | jetpack_vendor/automattic/jetpack-sync/src/modules/class-plugins.php +142 -86 13.4.5 → 16.3-a.7 View file →
@@ -9,8 +9,12 @@
9 9
10 10 use Automattic\Jetpack\Constants as Jetpack_Constants;
11 11 use WP_Error;
12 12
13 +if ( ! defined( 'ABSPATH' ) ) {
14 + exit( 0 );
15 +}
16 +
13 17 /**
14 18 * Class to handle sync for plugins.
15 19 */
16 20 class Plugins extends Module {
@@ -41,8 +45,44 @@
41 45 */
42 46 private $plugins = array();
43 47
44 48 /**
49 + * List of all updated plugins.
50 + *
51 + * @access private
52 + *
53 + * @var array
54 + */
55 + private $plugins_updated = array();
56 +
57 + /**
58 + * List of plugins installed during this request.
59 + *
60 + * @access private
61 + *
62 + * @var array
63 + */
64 + private $plugins_installed = array();
65 +
66 + /**
67 + * List of all plugin update failures during this request.
68 + *
69 + * @access private
70 + *
71 + * @var array
72 + */
73 + private $plugins_update_failures = array();
74 +
75 + /**
76 + * State
77 + *
78 + * @access private
79 + *
80 + * @var array
81 + */
82 + private $state = array();
83 +
84 + /**
45 85 * Sync module name.
46 86 *
47 87 * @access public
48 88 *
@@ -70,9 +110,8 @@
70 110 add_action( 'upgrader_process_complete', array( $this, 'on_upgrader_completion' ), 10, 2 );
71 111 add_action( 'jetpack_plugin_installed', $callable, 10, 1 );
72 112 add_action( 'jetpack_plugin_update_failed', $callable, 10, 4 );
73 113 add_action( 'jetpack_plugins_updated', $callable, 10, 2 );
74 - add_action( 'admin_action_update', array( $this, 'check_plugin_edit' ) );
75 114 add_action( 'jetpack_edited_plugin', $callable, 10, 2 );
76 115 add_action( 'wp_ajax_edit-theme-plugin-file', array( $this, 'plugin_edit_ajax' ), 0 );
77 116
78 117 // Note that we don't simply 'expand_plugin_data' on the 'delete_plugin' action here because the plugin file is deleted when that action finishes.
@@ -114,9 +153,9 @@
114 153 if ( ! isset( $details['action'] ) ) {
115 154 return;
116 155 }
117 156
118 - $plugins = ( isset( $details['plugins'] ) ? $details['plugins'] : null );
157 + $plugins = ( $details['plugins'] ?? null );
119 158 if ( empty( $plugins ) ) {
120 159 $plugins = ( isset( $details['plugin'] ) ? array( $details['plugin'] ) : null );
121 160 }
122 161
@@ -131,61 +170,43 @@
131 170 }
132 171
133 172 switch ( $details['action'] ) {
134 173 case 'update':
135 - $state = array(
174 + $this->state = array(
136 175 'is_autoupdate' => Jetpack_Constants::is_true( 'JETPACK_PLUGIN_AUTOUPDATE' ),
137 176 );
138 - $errors = $this->get_errors( $upgrader->skin );
177 + $errors = $this->get_errors( $upgrader->skin );
139 178 if ( $errors ) {
140 - foreach ( $plugins as $slug ) {
141 - /**
142 - * Sync that a plugin update failed
143 - *
144 - * @since 1.6.3
145 - * @since-jetpack 5.8.0
146 - *
147 - * @module sync
148 - *
149 - * @param string $plugin , Plugin slug
150 - * @param string Error code
151 - * @param string Error message
152 - */
153 - do_action( 'jetpack_plugin_update_failed', $this->get_plugin_info( $slug ), $errors['code'], $errors['message'], $state );
179 + foreach ( $plugins as $slug ) { // Accumulate failures and defer to shutdown, to reduce request-time lag.
180 + $this->plugins_update_failures[] = array(
181 + 'plugin' => $this->get_plugin_info( $slug ),
182 + 'code' => $errors['code'],
183 + 'message' => $errors['message'],
184 + 'state' => $this->state,
185 + );
154 186 }
187 + if ( ! has_action( 'shutdown', array( $this, 'sync_plugins_update_failed' ) ) ) {
188 + add_action( 'shutdown', array( $this, 'sync_plugins_update_failed' ), 9 );
189 + }
155 190
156 191 return;
157 192 }
158 - /**
159 - * Sync that a plugin update
160 - *
161 - * @since 1.6.3
162 - * @since-jetpack 5.8.0
163 - *
164 - * @module sync
165 - *
166 - * @param array () $plugin, Plugin Data
167 - */
168 - do_action( 'jetpack_plugins_updated', array_map( array( $this, 'get_plugin_info' ), $plugins ), $state );
193 +
194 + $this->plugins_updated = array_map( array( $this, 'get_plugin_info' ), $plugins );
195 + add_action( 'shutdown', array( $this, 'sync_plugins_updated' ), 9 );
196 +
169 197 break;
170 198 case 'install':
171 - }
199 + // Accumulate installs and defer to shutdown.
200 + $this->plugins_installed = array_merge(
201 + $this->plugins_installed,
202 + array_map( array( $this, 'get_plugin_info' ), $plugins )
203 + );
204 + if ( ! has_action( 'shutdown', array( $this, 'sync_plugins_installed' ) ) ) {
205 + add_action( 'shutdown', array( $this, 'sync_plugins_installed' ), 9 );
206 + }
172 207
173 - if ( 'install' === $details['action'] ) {
174 - /**
175 - * Signals to the sync listener that a plugin was installed and a sync action
176 - * reflecting the installation and the plugin info should be sent
177 - *
178 - * @since 1.6.3
179 - * @since-jetpack 5.8.0
180 - *
181 - * @module sync
182 - *
183 - * @param array () $plugin, Plugin Data
184 - */
185 - do_action( 'jetpack_plugin_installed', array_map( array( $this, 'get_plugin_info' ), $plugins ) );
186 -
187 - return;
208 + break;
188 209 }
189 210 }
190 211
191 212 /**
@@ -245,41 +266,8 @@
245 266 return false;
246 267 }
247 268
248 269 /**
249 - * Handle plugin edit in the administration.
250 - *
251 - * @access public
252 - *
253 - * @todo The `admin_action_update` hook is called only for logged in users, but maybe implement nonce verification?
254 - */
255 - public function check_plugin_edit() {
256 - $screen = get_current_screen();
257 - // phpcs:ignore WordPress.Security.NonceVerification.Missing
258 - if ( 'plugin-editor' !== $screen->base || ! isset( $_POST['newcontent'] ) || ! isset( $_POST['plugin'] ) ) {
259 - return;
260 - }
261 -
262 - // phpcs:ignore WordPress.Security.NonceVerification.Missing, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated manually just after.
263 - $plugin = wp_unslash( $_POST['plugin'] );
264 - $plugins = get_plugins();
265 - if ( ! isset( $plugins[ $plugin ] ) ) {
266 - return;
267 - }
268 -
269 - /**
270 - * Helps Sync log that a plugin was edited
271 - *
272 - * @since 1.6.3
273 - * @since-jetpack 4.9.0
274 - *
275 - * @param string $plugin, Plugin slug
276 - * @param mixed $plugins[ $plugin ], Array of plugin data
277 - */
278 - do_action( 'jetpack_edited_plugin', $plugin, $plugins[ $plugin ] );
279 - }
280 -
281 - /**
282 270 * Handle plugin ajax edit in the administration.
283 271 *
284 272 * @access public
285 273 *
@@ -286,36 +274,35 @@
286 274 * @todo Update this method to use WP_Filesystem instead of fopen/fclose.
287 275 */
288 276 public function plugin_edit_ajax() {
289 277 // This validation is based on wp_edit_theme_plugin_file().
290 - $args = wp_unslash( $_POST );
291 - if ( empty( $args['file'] ) ) {
278 + if ( empty( $_POST['file'] ) ) {
292 279 return;
293 280 }
294 281
295 - $file = $args['file'];
282 + $file = wp_unslash( $_POST['file'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated manually just after.
296 283 if ( 0 !== validate_file( $file ) ) {
297 284 return;
298 285 }
299 286
300 - if ( ! isset( $args['newcontent'] ) ) {
287 + if ( ! isset( $_POST['newcontent'] ) ) {
301 288 return;
302 289 }
303 290
304 - if ( ! isset( $args['nonce'] ) ) {
291 + if ( ! isset( $_POST['nonce'] ) ) {
305 292 return;
306 293 }
307 294
308 - if ( empty( $args['plugin'] ) ) {
295 + if ( empty( $_POST['plugin'] ) ) {
309 296 return;
310 297 }
311 298
312 - $plugin = $args['plugin'];
299 + $plugin = wp_unslash( $_POST['plugin'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated manually just after.
313 300 if ( ! current_user_can( 'edit_plugins' ) ) {
314 301 return;
315 302 }
316 303
317 - if ( ! wp_verify_nonce( $args['nonce'], 'edit-plugin_' . $file ) ) {
304 + if ( ! wp_verify_nonce( $_POST['nonce'], 'edit-plugin_' . $file ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- WP core doesn't pre-sanitize nonces either.
318 305 return;
319 306 }
320 307 $plugins = get_plugins();
321 308 if ( ! array_key_exists( $plugin, $plugins ) ) {
@@ -412,6 +399,75 @@
412 399 $args[0],
413 400 $args[1],
414 401 $plugin_data,
415 402 );
403 + }
404 +
405 + /**
406 + * Helper method for firing the 'jetpack_plugins_updated' action on shutdown.
407 + *
408 + * @access public
409 + */
410 + public function sync_plugins_updated() {
411 + /**
412 + * Sync that a plugin update
413 + *
414 + * @since 1.6.3
415 + * @since-jetpack 5.8.0
416 + *
417 + * @module sync
418 + *
419 + * @param array () $plugin, Plugin Data
420 + */
421 + do_action( 'jetpack_plugins_updated', $this->plugins_updated, $this->state );
422 + }
423 +
424 + /**
425 + * Helper method for firing the 'jetpack_plugin_installed' action on shutdown.
426 + *
427 + * @access public
428 + */
429 + public function sync_plugins_installed() {
430 + if ( empty( $this->plugins_installed ) ) {
431 + return;
432 + }
433 + /**
434 + * Signals to the sync listener that a plugin was installed and a sync action
435 + * reflecting the installation and the plugin info should be sent.
436 + *
437 + * @since 1.6.3
438 + * @since-jetpack 5.8.0
439 + *
440 + * @module sync
441 + *
442 + * @param array () $plugin, Plugin Data
443 + */
444 + do_action( 'jetpack_plugin_installed', $this->plugins_installed );
445 + }
446 +
447 + /**
448 + * Helper method for firing the 'jetpack_plugin_update_failed' actions on shutdown.
449 + *
450 + * @access public
451 + */
452 + public function sync_plugins_update_failed() {
453 + if ( empty( $this->plugins_update_failures ) ) {
454 + return;
455 + }
456 + foreach ( $this->plugins_update_failures as $failure ) {
457 + /**
458 + * Sync that a plugin update failed
459 + *
460 + * @since 1.6.3
461 + * @since-jetpack 5.8.0
462 + *
463 + * @module sync
464 + *
465 + * @param array $plugin Plugin Data
466 + * @param string $code Error code
467 + * @param string $message Error message
468 + * @param array $state State data
469 + */
470 + do_action( 'jetpack_plugin_update_failed', $failure['plugin'], $failure['code'], $failure['message'], $failure['state'] );
471 + }
416 472 }
417 473 }