PluginProbe
Polylang / 2.5
Polylang v2.5
3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 3.0.3 All 233 releases
← All changes | install/plugin-updater.php +49 -168 2.92.5 View file →
@@ -1,8 +1,5 @@
1 1 <?php
2 -/**
3 - * @package Polylang
4 - */
5 2
6 3 // Exit if accessed directly
7 4 if ( ! defined( 'ABSPATH' ) ) {
8 5 exit;
@@ -9,12 +6,12 @@
9 6 }
10 7
11 8 /**
12 9 * Allows plugins to use their own update API.
13 - * Modified version with 'polylang' text domain and comments for translators.
10 + * Modified version with 'polylang' text domain and comments for translators
14 11 *
15 12 * @author Easy Digital Downloads
16 - * @version 1.8.0
13 + * @version 1.6.16
17 14 */
18 15 class PLL_Plugin_Updater {
19 16
20 17 private $api_url = '';
@@ -24,10 +21,8 @@
24 21 private $version = '';
25 22 private $wp_override = false;
26 23 private $cache_key = '';
27 24
28 - private $health_check_timeout = 5;
29 -
30 25 /**
31 26 * Class constructor.
32 27 *
33 28 * @uses plugin_basename()
@@ -111,52 +106,31 @@
111 106 if ( ! empty( $_transient_data->response ) && ! empty( $_transient_data->response[ $this->name ] ) && false === $this->wp_override ) {
112 107 return $_transient_data;
113 108 }
114 109
115 - $current = $this->get_repo_api_data();
116 - if ( false !== $current && is_object( $current ) && isset( $current->new_version ) ) {
117 - if ( version_compare( $this->version, $current->new_version, '<' ) ) {
118 - $_transient_data->response[ $this->name ] = $current;
119 - } else {
120 - // Populating the no_update information is required to support auto-updates in WordPress 5.5.
121 - $_transient_data->no_update[ $this->name ] = $current;
122 - }
110 + $version_info = $this->get_cached_version_info();
111 +
112 + if ( false === $version_info ) {
113 + $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
114 +
115 + $this->set_version_info_cache( $version_info );
116 +
123 117 }
124 - $_transient_data->last_checked = time();
125 - $_transient_data->checked[ $this->name ] = $this->version;
126 118
127 - return $_transient_data;
128 - }
119 + if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
129 120
130 - /**
131 - * Get repo API data from store.
132 - * Save to cache.
133 - *
134 - * @return \stdClass
135 - */
136 - public function get_repo_api_data() {
137 - $version_info = $this->get_cached_version_info();
121 + if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
138 122
139 - if ( false === $version_info ) {
140 - $version_info = $this->api_request(
141 - 'plugin_latest_version',
142 - array(
143 - 'slug' => $this->slug,
144 - 'beta' => $this->beta,
145 - )
146 - );
147 - if ( ! $version_info ) {
148 - return false;
123 + $_transient_data->response[ $this->name ] = $version_info;
124 +
149 125 }
150 126
151 - // This is required for your plugin to support auto-updates in WordPress 5.5.
152 - $version_info->plugin = $this->name;
153 - $version_info->id = $this->name;
127 + $_transient_data->last_checked = time();
128 + $_transient_data->checked[ $this->name ] = $this->version;
154 129
155 - $this->set_version_info_cache( $version_info );
156 130 }
157 131
158 - return $version_info;
132 + return $_transient_data;
159 133 }
160 134
161 135 /**
162 136 * show update nofication row -- needed for multisite subsites, because WP won't tell you otherwise!
@@ -190,30 +164,13 @@
190 164 $update_cache = is_object( $update_cache ) ? $update_cache : new stdClass();
191 165
192 166 if ( empty( $update_cache->response ) || empty( $update_cache->response[ $this->name ] ) ) {
193 167
194 - $version_info = $this->get_repo_api_data();
168 + $version_info = $this->get_cached_version_info();
195 169
196 170 if ( false === $version_info ) {
197 171 $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
198 172
199 - // Since we disabled our filter for the transient, we aren't running our object conversion on banners, sections, or icons. Do this now:
200 - if ( isset( $version_info->banners ) && ! is_array( $version_info->banners ) ) {
201 - $version_info->banners = $this->convert_object_to_array( $version_info->banners );
202 - }
203 -
204 - if ( isset( $version_info->sections ) && ! is_array( $version_info->sections ) ) {
205 - $version_info->sections = $this->convert_object_to_array( $version_info->sections );
206 - }
207 -
208 - if ( isset( $version_info->icons ) && ! is_array( $version_info->icons ) ) {
209 - $version_info->icons = $this->convert_object_to_array( $version_info->icons );
210 - }
211 -
212 - if ( isset( $version_info->contributors ) && ! is_array( $version_info->contributors ) ) {
213 - $version_info->contributors = $this->convert_object_to_array( $version_info->contributors );
214 - }
215 -
216 173 $this->set_version_info_cache( $version_info );
217 174 }
218 175
219 176 if ( ! is_object( $version_info ) ) {
@@ -220,14 +177,14 @@
220 177 return;
221 178 }
222 179
223 180 if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
181 +
224 182 $update_cache->response[ $this->name ] = $version_info;
225 - } else {
226 - $update_cache->no_update[ $this->name ] = $version_info;
183 +
227 184 }
228 185
229 - $update_cache->last_checked = time();
186 + $update_cache->last_checked = time();
230 187 $update_cache->checked[ $this->name ] = $this->version;
231 188
232 189 set_site_transient( 'update_plugins', $update_cache );
233 190
@@ -307,15 +264,16 @@
307 264 'slug' => $this->slug,
308 265 'is_ssl' => is_ssl(),
309 266 'fields' => array(
310 267 'banners' => array(),
311 - 'reviews' => false,
312 - 'icons' => array(),
268 + 'reviews' => false
313 269 )
314 270 );
315 271
272 + $cache_key = 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );
273 +
316 274 // Get the transient where we store the api request for this plugin for 24 hours
317 - $edd_api_request_transient = $this->get_cached_version_info();
275 + $edd_api_request_transient = $this->get_cached_version_info( $cache_key );
318 276
319 277 //If we have no transient-saved value, run the API, set a fresh transient with the API value, and return that value too right now.
320 278 if ( empty( $edd_api_request_transient ) ) {
321 279
@@ -321,9 +279,9 @@
321 279
322 280 $api_response = $this->api_request( 'plugin_information', $to_send );
323 281
324 282 // Expires in 3 hours
325 - $this->set_version_info_cache( $api_response );
283 + $this->set_version_info_cache( $api_response, $cache_key );
326 284
327 285 if ( false !== $api_response ) {
328 286 $_data = $api_response;
329 287 }
@@ -333,55 +291,30 @@
333 291 }
334 292
335 293 // Convert sections into an associative array, since we're getting an object, but Core expects an array.
336 294 if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
337 - $_data->sections = $this->convert_object_to_array( $_data->sections );
295 + $new_sections = array();
296 + foreach ( $_data->sections as $key => $value ) {
297 + $new_sections[ $key ] = $value;
298 + }
299 +
300 + $_data->sections = $new_sections;
338 301 }
339 302
340 303 // Convert banners into an associative array, since we're getting an object, but Core expects an array.
341 304 if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
342 - $_data->banners = $this->convert_object_to_array( $_data->banners );
343 - }
305 + $new_banners = array();
306 + foreach ( $_data->banners as $key => $value ) {
307 + $new_banners[ $key ] = $value;
308 + }
344 309
345 - // Convert icons into an associative array, since we're getting an object, but Core expects an array.
346 - if ( isset( $_data->icons ) && ! is_array( $_data->icons ) ) {
347 - $_data->icons = $this->convert_object_to_array( $_data->icons );
310 + $_data->banners = $new_banners;
348 311 }
349 312
350 - // Convert contributors into an associative array, since we're getting an object, but Core expects an array.
351 - if ( isset( $_data->contributors ) && ! is_array( $_data->contributors ) ) {
352 - $_data->contributors = $this->convert_object_to_array( $_data->contributors );
353 - }
354 -
355 - if( ! isset( $_data->plugin ) ) {
356 - $_data->plugin = $this->name;
357 - }
358 -
359 313 return $_data;
360 314 }
361 315
362 316 /**
363 - * Convert some objects to arrays when injecting data into the update API
364 - *
365 - * Some data like sections, banners, and icons are expected to be an associative array, however due to the JSON
366 - * decoding, they are objects. This method allows us to pass in the object and return an associative array.
367 - *
368 - * @since 3.6.5
369 - *
370 - * @param stdClass $data
371 - *
372 - * @return array
373 - */
374 - private function convert_object_to_array( $data ) {
375 - $new_data = array();
376 - foreach ( $data as $key => $value ) {
377 - $new_data[ $key ] = is_object( $value ) ? $this->convert_object_to_array( $value ) : $value;
378 - }
379 -
380 - return $new_data;
381 - }
382 -
383 - /**
384 317 * Disable SSL verification in order to prevent download update failures
385 318 *
386 319 * @param array $args
387 320 * @param string $url
@@ -409,41 +342,17 @@
409 342 * @return false|object
410 343 */
411 344 private function api_request( $_action, $_data ) {
412 345
413 - global $wp_version, $edd_plugin_url_available;
346 + global $wp_version;
414 347
415 - $verify_ssl = $this->verify_ssl();
416 -
417 - // Do a quick status check on this domain if we haven't already checked it.
418 - $store_hash = md5( $this->api_url );
419 - if ( ! is_array( $edd_plugin_url_available ) || ! isset( $edd_plugin_url_available[ $store_hash ] ) ) {
420 - $test_url_parts = parse_url( $this->api_url );
421 -
422 - $scheme = ! empty( $test_url_parts['scheme'] ) ? $test_url_parts['scheme'] : 'http';
423 - $host = ! empty( $test_url_parts['host'] ) ? $test_url_parts['host'] : '';
424 - $port = ! empty( $test_url_parts['port'] ) ? ':' . $test_url_parts['port'] : '';
425 -
426 - if ( empty( $host ) ) {
427 - $edd_plugin_url_available[ $store_hash ] = false;
428 - } else {
429 - $test_url = $scheme . '://' . $host . $port;
430 - $response = wp_remote_get( $test_url, array( 'timeout' => $this->health_check_timeout, 'sslverify' => $verify_ssl ) );
431 - $edd_plugin_url_available[ $store_hash ] = is_wp_error( $response ) ? false : true;
432 - }
433 - }
434 -
435 - if ( false === $edd_plugin_url_available[ $store_hash ] ) {
436 - return false;
437 - }
438 -
439 348 $data = array_merge( $this->api_data, $_data );
440 349
441 350 if ( $data['slug'] != $this->slug ) {
442 - return false;
351 + return;
443 352 }
444 353
445 - if ( $this->api_url == trailingslashit ( home_url() ) ) {
354 + if( $this->api_url == trailingslashit (home_url() ) ) {
446 355 return false; // Don't allow a plugin to ping itself
447 356 }
448 357
449 358 $api_params = array(
@@ -457,8 +366,9 @@
457 366 'url' => home_url(),
458 367 'beta' => ! empty( $data['beta'] ),
459 368 );
460 369
370 + $verify_ssl = $this->verify_ssl();
461 371 $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) );
462 372
463 373 if ( ! is_wp_error( $request ) ) {
464 374 $request = json_decode( wp_remote_retrieve_body( $request ) );
@@ -473,13 +383,9 @@
473 383 if ( $request && isset( $request->banners ) ) {
474 384 $request->banners = maybe_unserialize( $request->banners );
475 385 }
476 386
477 - if ( $request && isset( $request->icons ) ) {
478 - $request->icons = maybe_unserialize( $request->icons );
479 - }
480 -
481 - if ( ! empty( $request->sections ) ) {
387 + if( ! empty( $request->sections ) ) {
482 388 foreach( $request->sections as $key => $section ) {
483 389 $request->$key = (array) $section;
484 390 }
485 391 }
@@ -486,11 +392,8 @@
486 392
487 393 return $request;
488 394 }
489 395
490 - /**
491 - * If available, show the changelog for sites in a multisite install.
492 - */
493 396 public function show_changelog() {
494 397
495 398 global $edd_plugin_data;
496 399
@@ -510,9 +413,11 @@
510 413 wp_die( __( 'You do not have permission to install plugin updates', 'polylang' ), __( 'Error', 'polylang' ), array( 'response' => 403 ) );
511 414 }
512 415
513 416 $data = $edd_plugin_data[ $_REQUEST['slug'] ];
514 - $version_info = $this->get_cached_version_info();
417 + $beta = ! empty( $data['beta'] ) ? true : false;
418 + $cache_key = md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $beta . '_version_info' );
419 + $version_info = $this->get_cached_version_info( $cache_key );
515 420
516 421 if( false === $version_info ) {
517 422
518 423 $api_params = array(
@@ -531,8 +436,9 @@
531 436 if ( ! is_wp_error( $request ) ) {
532 437 $version_info = json_decode( wp_remote_retrieve_body( $request ) );
533 438 }
534 439
440 +
535 441 if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
536 442 $version_info->sections = maybe_unserialize( $version_info->sections );
537 443 } else {
538 444 $version_info = false;
@@ -543,30 +449,19 @@
543 449 $version_info->$key = (array) $section;
544 450 }
545 451 }
546 452
547 - $this->set_version_info_cache( $version_info );
453 + $this->set_version_info_cache( $version_info, $cache_key );
548 454
549 - // Delete the unneeded option
550 - delete_option( md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $this->beta . '_version_info' ) );
551 455 }
552 456
553 - if ( isset( $version_info->sections ) ) {
554 - $sections = $this->convert_object_to_array( $version_info->sections );
555 - if ( ! empty( $sections['changelog'] ) ) {
556 - echo '<div style="background:#fff;padding:10px;">' . wp_kses_post( $sections['changelog'] ) . '</div>';
557 - }
457 + if( ! empty( $version_info ) && isset( $version_info->sections['changelog'] ) ) {
458 + echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>';
558 459 }
559 460
560 461 exit;
561 462 }
562 463
563 - /**
564 - * Gets the plugin's cached version information from the database.
565 - *
566 - * @param string $cache_key
567 - * @return boolean|string
568 - */
569 464 public function get_cached_version_info( $cache_key = '' ) {
570 465
571 466 if( empty( $cache_key ) ) {
572 467 $cache_key = $this->cache_key;
@@ -577,24 +472,12 @@
577 472 if( empty( $cache['timeout'] ) || time() > $cache['timeout'] ) {
578 473 return false; // Cache is expired
579 474 }
580 475
581 - // We need to turn the icons into an array, thanks to WP Core forcing these into an object at some point.
582 - $cache['value'] = json_decode( $cache['value'] );
583 - if ( ! empty( $cache['value']->icons ) ) {
584 - $cache['value']->icons = (array) $cache['value']->icons;
585 - }
476 + return json_decode( $cache['value'] );
586 477
587 - return $cache['value'];
588 -
589 478 }
590 479
591 - /**
592 - * Adds the plugin version information to the database.
593 - *
594 - * @param string $value
595 - * @param string $cache_key
596 - */
597 480 public function set_version_info_cache( $value = '', $cache_key = '' ) {
598 481
599 482 if( empty( $cache_key ) ) {
600 483 $cache_key = $this->cache_key;
@@ -606,10 +489,8 @@
606 489 );
607 490
608 491 update_option( $cache_key, $data, 'no' );
609 492
610 - // Delete the duplicate option
611 - delete_option( 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ) );
612 493 }
613 494
614 495 /**
615 496 * Returns if the SSL of the store should be verified.