PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 14.9.2
Jetpack – WP Security, Backup, Speed, & Growth v14.9.2
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 14.5.1 14.6.1 14.7.1 14.8.1 14.9.2 15.0.3 15.1.2 15.2.1 15.3.2 15.4.1 15.5.1 15.6.1 15.7.2 15.8.1 15.9.2 16.0.2 16.1.3 16.2-a.5 16.2-a.3 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 / class.jetpack-autoupdate.php
jetpack Last commit date
3rd-party 1 year ago _inc 1 day ago css 1 year ago extensions 1 year ago images 1 year ago jetpack_vendor 1 day ago json-endpoints 1 year ago modules 1 year ago sal 1 year ago src 1 year ago vendor 1 year ago views 2 years ago CHANGELOG.md 1 year ago LICENSE.txt 5 years ago SECURITY.md 2 years ago class-jetpack-connection-status.php 2 years ago class-jetpack-gallery-settings.php 1 year ago class-jetpack-newsletter-dashboard-widget.php 1 year ago class-jetpack-pre-connection-jitms.php 2 years ago class-jetpack-stats-dashboard-widget.php 1 year ago class-jetpack-xmlrpc-methods.php 1 year ago class.frame-nonce-preview.php 1 year ago class.jetpack-admin.php 1 year ago class.jetpack-autoupdate.php 1 year ago class.jetpack-cli.php 1 year ago class.jetpack-client-server.php 2 years ago class.jetpack-gutenberg.php 1 year ago class.jetpack-heartbeat.php 2 years ago class.jetpack-modules-list-table.php 1 year ago class.jetpack-network-sites-list-table.php 2 years ago class.jetpack-network.php 1 year ago class.jetpack-plan.php 3 years ago class.jetpack-post-images.php 1 year ago class.jetpack-twitter-cards.php 2 years ago class.jetpack-user-agent.php 2 years ago class.jetpack.php 1 year ago class.json-api-endpoints.php 1 year ago class.json-api.php 1 year ago class.photon.php 3 years ago composer.json 1 year ago enhanced-open-graph.php 1 year ago functions.compat.php 1 year ago functions.cookies.php 2 years ago functions.global.php 1 year ago functions.is-mobile.php 2 years ago functions.opengraph.php 1 year ago functions.photon.php 2 years ago jetpack.php 1 day ago json-api-config.php 3 years ago json-endpoints.php 2 years ago load-jetpack.php 1 year ago locales.php 4 years ago readme.txt 1 day ago unauth-file-upload.php 1 year ago uninstall.php 1 year ago wpml-config.xml 4 years ago
class.jetpack-autoupdate.php
376 lines
1 <?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2 /**
3 * Handles items that have been selected for automatic updates.
4 * Hooks into WP_Automatic_Updater
5 *
6 * @package automattic/jetpack
7 */
8
9 /**
10 * Handles items that have been selected for automatic updates.
11 * Hooks into WP_Automatic_Updater
12 */
13 class Jetpack_Autoupdate {
14
15 /**
16 * Results.
17 *
18 * @var array
19 */
20 private $results = array();
21
22 /**
23 * Expected updates.
24 *
25 * @var array
26 */
27 private $expected = array();
28
29 /**
30 * Successful updates.
31 *
32 * @var array
33 */
34 private $success = array(
35 'plugin' => array(),
36 'theme' => array(),
37 );
38
39 /**
40 * Failed updates.
41 *
42 * @var array
43 */
44 private $failed = array(
45 'plugin' => array(),
46 'theme' => array(),
47 );
48
49 /**
50 * Static instance.
51 *
52 * @var self
53 */
54 private static $instance = null;
55
56 /**
57 * Initialize and fetch the static instance.
58 *
59 * @return self
60 */
61 public static function init() {
62 if ( self::$instance === null ) {
63 self::$instance = new Jetpack_Autoupdate();
64 }
65
66 return self::$instance;
67 }
68
69 /** Constructor. */
70 private function __construct() {
71 if (
72 /** This filter is documented in class.jetpack-json-api-endpoint.php */
73 apply_filters( 'jetpack_json_manage_api_enabled', true )
74 ) {
75 add_filter( 'auto_update_theme', array( $this, 'autoupdate_theme' ), 10, 2 );
76 add_filter( 'auto_update_core', array( $this, 'autoupdate_core' ), 10, 2 );
77 add_filter( 'auto_update_translation', array( $this, 'autoupdate_translation' ), 10, 2 );
78 add_action( 'automatic_updates_complete', array( $this, 'automatic_updates_complete' ), 999, 1 );
79 }
80 }
81
82 /**
83 * Filter function for `auto_update_translation`.
84 *
85 * @param bool|null $update Whether to update.
86 * @param object $item The update offer.
87 * @return bool|null Whether to update.
88 */
89 public function autoupdate_translation( $update, $item ) {
90 // Autoupdate all translations.
91 if ( Jetpack_Options::get_option( 'autoupdate_translations', false ) ) {
92 return true;
93 }
94
95 if ( ! isset( $item->slug ) || ! isset( $item->type ) ) {
96 return $update;
97 }
98
99 // Themes.
100 $autoupdate_themes_translations = Jetpack_Options::get_option( 'autoupdate_themes_translations', array() );
101 $autoupdate_theme_list = Jetpack_Options::get_option( 'autoupdate_themes', array() );
102
103 if ( ( in_array( $item->slug, $autoupdate_themes_translations, true ) || in_array( $item->slug, $autoupdate_theme_list, true ) )
104 && 'theme' === $item->type
105 ) {
106 $this->expect( $item->type . ':' . $item->slug, 'translation' );
107
108 return true;
109 }
110
111 // Plugins.
112 $autoupdate_plugin_translations = Jetpack_Options::get_option( 'autoupdate_plugins_translations', array() );
113 $autoupdate_plugin_list = (array) get_site_option( 'auto_update_plugins', array() );
114 $plugin_files = array_unique( array_merge( $autoupdate_plugin_list, $autoupdate_plugin_translations ) );
115 $plugin_slugs = array_map( array( __CLASS__, 'get_plugin_slug' ), $plugin_files );
116
117 if ( in_array( $item->slug, $plugin_slugs, true )
118 && 'plugin' === $item->type
119 ) {
120 $this->expect( $item->type . ':' . $item->slug, 'translation' );
121 return true;
122 }
123
124 return $update;
125 }
126
127 /**
128 * Filter function for `auto_update_theme`.
129 *
130 * @param bool|null $update Whether to update.
131 * @param object $item The update offer.
132 * @return bool|null Whether to update.
133 */
134 public function autoupdate_theme( $update, $item ) {
135 if ( ! isset( $item->theme ) ) {
136 return $update;
137 }
138 $autoupdate_theme_list = Jetpack_Options::get_option( 'autoupdate_themes', array() );
139 if ( in_array( $item->theme, $autoupdate_theme_list, true ) ) {
140 $this->expect( $item->theme, 'theme' );
141 return true;
142 }
143
144 return $update;
145 }
146
147 /**
148 * Filter function for `auto_update_core`.
149 *
150 * @param bool|null $update Whether to update.
151 * @return bool|null Whether to update.
152 */
153 public function autoupdate_core( $update ) {
154 $autoupdate_core = Jetpack_Options::get_option( 'autoupdate_core', false );
155 if ( $autoupdate_core ) {
156 return $autoupdate_core;
157 }
158
159 return $update;
160 }
161
162 /**
163 * Stores the an item identifier to the expected array.
164 *
165 * @param string $item Example: 'jetpack/jetpack.php' for type 'plugin' or 'twentyfifteen' for type 'theme'.
166 * @param string $type 'plugin' or 'theme'.
167 */
168 private function expect( $item, $type ) {
169 if ( ! isset( $this->expected[ $type ] ) ) {
170 $this->expected[ $type ] = array();
171 }
172 $this->expected[ $type ][] = $item;
173 }
174
175 /**
176 * On completion of an automatic update, let's store the results.
177 *
178 * @param mixed $results - Sent by WP_Automatic_Updater after it completes an autoupdate action. Results may be empty.
179 */
180 public function automatic_updates_complete( $results ) {
181 if ( empty( $this->expected ) ) {
182 return;
183 }
184 $this->results = empty( $results ) ? self::get_possible_failures() : $results;
185
186 add_action( 'shutdown', array( $this, 'bump_stats' ) );
187
188 Jetpack::init();
189
190 $items_to_log = array( 'plugin', 'theme', 'translation' );
191 foreach ( $items_to_log as $items ) {
192 $this->log_items( $items );
193 }
194
195 Jetpack::log( 'autoupdates', $this->get_log() );
196 }
197
198 /**
199 * Get log data.
200 *
201 * @return array Data.
202 */
203 public function get_log() {
204 return array(
205 'results' => $this->results,
206 'failed' => $this->failed,
207 'success' => $this->success,
208 );
209 }
210
211 /**
212 * Iterates through expected items ( plugins or themes ) and compares them to actual results.
213 *
214 * @param string $items 'plugin' or 'theme'.
215 */
216 private function log_items( $items ) {
217 if ( ! isset( $this->expected[ $items ] ) ) {
218 return;
219 }
220
221 $item_results = $this->get_successful_updates( $items );
222
223 if ( is_array( $this->expected[ $items ] ) ) {
224 foreach ( $this->expected[ $items ] as $item ) {
225 if ( in_array( $item, $item_results, true ) ) {
226 $this->success[ $items ][] = $item;
227 } else {
228 $this->failed[ $items ][] = $item;
229 }
230 }
231 }
232 }
233
234 /**
235 * Bump stats.
236 */
237 public function bump_stats() {
238 $instance = Jetpack::init();
239 $log = array();
240 // Bump numbers.
241
242 if ( ! empty( $this->success['theme'] ) ) {
243 $instance->stat( 'autoupdates/theme-success', is_countable( $this->success['theme'] ) ? count( $this->success['theme'] ) : 0 );
244 $log['themes_success'] = $this->success['theme'];
245 }
246
247 if ( ! empty( $this->failed['theme'] ) ) {
248 $instance->stat( 'autoupdates/theme-fail', is_countable( $this->failed['theme'] ) ? count( $this->failed['theme'] ) : 0 );
249 $log['themes_failed'] = $this->failed['theme'];
250 }
251
252 $instance->do_stats( 'server_side' );
253
254 // Send a more detailed log to logstash.
255 if ( ! empty( $log ) ) {
256 $xml = new Jetpack_IXR_Client(
257 array(
258 'user_id' => get_current_user_id(),
259 )
260 );
261 $log['blog_id'] = Jetpack_Options::get_option( 'id' );
262 $xml->query( 'jetpack.debug_autoupdate', $log );
263 }
264 }
265
266 /**
267 * Parses the autoupdate results generated by WP_Automatic_Updater and returns a simple array of successful items.
268 *
269 * @param string $type 'plugin' or 'theme'.
270 * @return array
271 */
272 private function get_successful_updates( $type ) {
273 $successful_updates = array();
274
275 if ( ! isset( $this->results[ $type ] ) ) {
276 return $successful_updates;
277 }
278
279 foreach ( $this->results[ $type ] as $result ) {
280 if ( $result->result ) {
281 switch ( $type ) {
282 case 'theme':
283 $successful_updates[] = $result->item->theme;
284 break;
285 case 'translation':
286 $successful_updates[] = $result->item->type . ':' . $result->item->slug;
287 break;
288 }
289 }
290 }
291
292 return $successful_updates;
293 }
294
295 /**
296 * Get possible failure codes.
297 *
298 * @return string[] Failure codes.
299 */
300 public static function get_possible_failures() {
301 $result = array();
302 // Lets check some reasons why it might not be working as expected.
303 include_once ABSPATH . '/wp-admin/includes/admin.php';
304 include_once ABSPATH . '/wp-admin/includes/class-wp-upgrader.php';
305 $upgrader = new WP_Automatic_Updater();
306
307 if ( $upgrader->is_disabled() ) {
308 $result[] = 'autoupdates-disabled';
309 }
310 if ( ! is_main_site() ) {
311 $result[] = 'is-not-main-site';
312 }
313 if ( ! is_main_network() ) {
314 $result[] = 'is-not-main-network';
315 }
316 if ( $upgrader->is_vcs_checkout( ABSPATH ) ) {
317 $result[] = 'site-on-vcs';
318 }
319 if ( $upgrader->is_vcs_checkout( WP_PLUGIN_DIR ) ) {
320 $result[] = 'plugin-directory-on-vcs';
321 }
322 if ( $upgrader->is_vcs_checkout( WP_CONTENT_DIR ) ) {
323 $result[] = 'content-directory-on-vcs';
324 }
325 $lock = get_option( 'auto_updater.lock' );
326 if ( $lock > ( time() - HOUR_IN_SECONDS ) ) {
327 $result[] = 'lock-is-set';
328 }
329 $skin = new Automatic_Upgrader_Skin();
330 include_once ABSPATH . 'wp-admin/includes/file.php';
331 include_once ABSPATH . 'wp-admin/includes/template.php';
332 if ( ! $skin->request_filesystem_credentials( false, ABSPATH, false ) ) {
333 $result[] = 'no-system-write-access';
334 }
335 if ( ! $skin->request_filesystem_credentials( false, WP_PLUGIN_DIR, false ) ) {
336 $result[] = 'no-plugin-directory-write-access';
337 }
338 if ( ! $skin->request_filesystem_credentials( false, WP_CONTENT_DIR, false ) ) {
339 $result[] = 'no-wp-content-directory-write-access';
340 }
341
342 return $result;
343 }
344
345 /**
346 * Get the plugin slug.
347 *
348 * @param string $plugin_file Plugin file.
349 * @return string Slug.
350 */
351 public static function get_plugin_slug( $plugin_file ) {
352 $update_plugins = get_site_transient( 'update_plugins' );
353 if ( isset( $update_plugins->no_update ) ) {
354 if ( isset( $update_plugins->no_update[ $plugin_file ]->slug ) ) {
355 $slug = $update_plugins->no_update[ $plugin_file ]->slug;
356 }
357 }
358 if ( empty( $slug ) && isset( $update_plugins->response ) ) {
359 if ( isset( $update_plugins->response[ $plugin_file ]->slug ) ) {
360 $slug = $update_plugins->response[ $plugin_file ]->slug;
361 }
362 }
363
364 // Try to infer from the plugin file if not cached.
365 if ( empty( $slug ) ) {
366 $slug = dirname( $plugin_file );
367 if ( '.' === $slug ) {
368 $slug = preg_replace( '/(.+)\.php$/', '$1', $plugin_file );
369 }
370 }
371 return $slug;
372 }
373 }
374
375 Jetpack_Autoupdate::init();
376