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 +29 -161 2.82.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;
@@ -12,9 +9,9 @@
12 9 * Allows plugins to use their own update API.
13 10 * Modified version with 'polylang' text domain and comments for translators
14 11 *
15 12 * @author Easy Digital Downloads
16 - * @version 1.7.1
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()
@@ -122,35 +117,17 @@
122 117 }
123 118
124 119 if ( false !== $version_info && is_object( $version_info ) && isset( $version_info->new_version ) ) {
125 120
126 - $no_update = false;
127 121 if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
128 122
129 123 $_transient_data->response[ $this->name ] = $version_info;
130 124
131 - // Make sure the plugin property is set to the plugin's name/location. See issue 1463 on Software Licensing's GitHub repo.
132 - $_transient_data->response[ $this->name ]->plugin = $this->name;
133 -
134 - } else {
135 - $no_update = new stdClass();
136 - $no_update->id = '';
137 - $no_update->slug = $this->slug;
138 - $no_update->plugin = $this->name;
139 - $no_update->new_version = $version_info->new_version;
140 - $no_update->url = $version_info->homepage;
141 - $no_update->package = isset( $version_info->package ) ? $version_info->package : ''; #modified#
142 - $no_update->icons = $version_info->icons;
143 - $no_update->banners = $version_info->banners;
144 - $no_update->banners_rtl = array();
145 125 }
146 126
147 127 $_transient_data->last_checked = time();
148 128 $_transient_data->checked[ $this->name ] = $this->version;
149 129
150 - if ( $no_update ) {
151 - $_transient_data->no_update[ $this->name ] = $no_update;
152 - }
153 130 }
154 131
155 132 return $_transient_data;
156 133 }
@@ -192,25 +169,8 @@
192 169
193 170 if ( false === $version_info ) {
194 171 $version_info = $this->api_request( 'plugin_latest_version', array( 'slug' => $this->slug, 'beta' => $this->beta ) );
195 172
196 - // Since we disabled our filter for the transient, we aren't running our object conversion on banners, sections, or icons. Do this now:
197 - if ( isset( $version_info->banners ) && ! is_array( $version_info->banners ) ) {
198 - $version_info->banners = $this->convert_object_to_array( $version_info->banners );
199 - }
200 -
201 - if ( isset( $version_info->sections ) && ! is_array( $version_info->sections ) ) {
202 - $version_info->sections = $this->convert_object_to_array( $version_info->sections );
203 - }
204 -
205 - if ( isset( $version_info->icons ) && ! is_array( $version_info->icons ) ) {
206 - $version_info->icons = $this->convert_object_to_array( $version_info->icons );
207 - }
208 -
209 - if ( isset( $version_info->contributors ) && ! is_array( $version_info->contributors ) ) {
210 - $version_info->contributors = $this->convert_object_to_array( $version_info->contributors );
211 - }
212 -
213 173 $this->set_version_info_cache( $version_info );
214 174 }
215 175
216 176 if ( ! is_object( $version_info ) ) {
@@ -216,31 +176,16 @@
216 176 if ( ! is_object( $version_info ) ) {
217 177 return;
218 178 }
219 179
220 - $no_update = false;
221 180 if ( version_compare( $this->version, $version_info->new_version, '<' ) ) {
222 181
223 182 $update_cache->response[ $this->name ] = $version_info;
224 183
225 - } else {
226 - $no_update = new stdClass();
227 - $no_update->id = '';
228 - $no_update->slug = $this->slug;
229 - $no_update->plugin = $this->name;
230 - $no_update->new_version = $version_info->new_version;
231 - $no_update->url = $version_info->homepage;
232 - $no_update->package = isset( $version_info->package ) ? $version_info->package : ''; #modified#
233 - $no_update->icons = $version_info->icons;
234 - $no_update->banners = $version_info->banners;
235 - $no_update->banners_rtl = array();
236 184 }
237 185
238 - $update_cache->last_checked = time();
186 + $update_cache->last_checked = time();
239 187 $update_cache->checked[ $this->name ] = $this->version;
240 - if ( $no_update ) {
241 - $update_cache->no_update[ $this->name ] = $no_update;
242 - }
243 188
244 189 set_site_transient( 'update_plugins', $update_cache );
245 190
246 191 } else {
@@ -319,15 +264,16 @@
319 264 'slug' => $this->slug,
320 265 'is_ssl' => is_ssl(),
321 266 'fields' => array(
322 267 'banners' => array(),
323 - 'reviews' => false,
324 - 'icons' => array(),
268 + 'reviews' => false
325 269 )
326 270 );
327 271
272 + $cache_key = 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) );
273 +
328 274 // Get the transient where we store the api request for this plugin for 24 hours
329 - $edd_api_request_transient = $this->get_cached_version_info();
275 + $edd_api_request_transient = $this->get_cached_version_info( $cache_key );
330 276
331 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.
332 278 if ( empty( $edd_api_request_transient ) ) {
333 279
@@ -333,9 +279,9 @@
333 279
334 280 $api_response = $this->api_request( 'plugin_information', $to_send );
335 281
336 282 // Expires in 3 hours
337 - $this->set_version_info_cache( $api_response );
283 + $this->set_version_info_cache( $api_response, $cache_key );
338 284
339 285 if ( false !== $api_response ) {
340 286 $_data = $api_response;
341 287 }
@@ -345,55 +291,30 @@
345 291 }
346 292
347 293 // Convert sections into an associative array, since we're getting an object, but Core expects an array.
348 294 if ( isset( $_data->sections ) && ! is_array( $_data->sections ) ) {
349 - $_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;
350 301 }
351 302
352 303 // Convert banners into an associative array, since we're getting an object, but Core expects an array.
353 304 if ( isset( $_data->banners ) && ! is_array( $_data->banners ) ) {
354 - $_data->banners = $this->convert_object_to_array( $_data->banners );
355 - }
305 + $new_banners = array();
306 + foreach ( $_data->banners as $key => $value ) {
307 + $new_banners[ $key ] = $value;
308 + }
356 309
357 - // Convert icons into an associative array, since we're getting an object, but Core expects an array.
358 - if ( isset( $_data->icons ) && ! is_array( $_data->icons ) ) {
359 - $_data->icons = $this->convert_object_to_array( $_data->icons );
310 + $_data->banners = $new_banners;
360 311 }
361 312
362 - // Convert contributors into an associative array, since we're getting an object, but Core expects an array.
363 - if ( isset( $_data->contributors ) && ! is_array( $_data->contributors ) ) {
364 - $_data->contributors = $this->convert_object_to_array( $_data->contributors );
365 - }
366 -
367 - if( ! isset( $_data->plugin ) ) {
368 - $_data->plugin = $this->name;
369 - }
370 -
371 313 return $_data;
372 314 }
373 315
374 316 /**
375 - * Convert some objects to arrays when injecting data into the update API
376 - *
377 - * Some data like sections, banners, and icons are expected to be an associative array, however due to the JSON
378 - * decoding, they are objects. This method allows us to pass in the object and return an associative array.
379 - *
380 - * @since 3.6.5
381 - *
382 - * @param stdClass $data
383 - *
384 - * @return array
385 - */
386 - private function convert_object_to_array( $data ) {
387 - $new_data = array();
388 - foreach ( $data as $key => $value ) {
389 - $new_data[ $key ] = is_object( $value ) ? $this->convert_object_to_array( $value ) : $value;
390 - }
391 -
392 - return $new_data;
393 - }
394 -
395 - /**
396 317 * Disable SSL verification in order to prevent download update failures
397 318 *
398 319 * @param array $args
399 320 * @param string $url
@@ -421,34 +342,10 @@
421 342 * @return false|object
422 343 */
423 344 private function api_request( $_action, $_data ) {
424 345
425 - global $wp_version, $edd_plugin_url_available;
346 + global $wp_version;
426 347
427 - $verify_ssl = $this->verify_ssl();
428 -
429 - // Do a quick status check on this domain if we haven't already checked it.
430 - $store_hash = md5( $this->api_url );
431 - if ( ! is_array( $edd_plugin_url_available ) || ! isset( $edd_plugin_url_available[ $store_hash ] ) ) {
432 - $test_url_parts = parse_url( $this->api_url );
433 -
434 - $scheme = ! empty( $test_url_parts['scheme'] ) ? $test_url_parts['scheme'] : 'http';
435 - $host = ! empty( $test_url_parts['host'] ) ? $test_url_parts['host'] : '';
436 - $port = ! empty( $test_url_parts['port'] ) ? ':' . $test_url_parts['port'] : '';
437 -
438 - if ( empty( $host ) ) {
439 - $edd_plugin_url_available[ $store_hash ] = false;
440 - } else {
441 - $test_url = $scheme . '://' . $host . $port;
442 - $response = wp_remote_get( $test_url, array( 'timeout' => $this->health_check_timeout, 'sslverify' => $verify_ssl ) );
443 - $edd_plugin_url_available[ $store_hash ] = is_wp_error( $response ) ? false : true;
444 - }
445 - }
446 -
447 - if ( false === $edd_plugin_url_available[ $store_hash ] ) {
448 - return;
449 - }
450 -
451 348 $data = array_merge( $this->api_data, $_data );
452 349
453 350 if ( $data['slug'] != $this->slug ) {
454 351 return;
@@ -453,9 +350,9 @@
453 350 if ( $data['slug'] != $this->slug ) {
454 351 return;
455 352 }
456 353
457 - if( $this->api_url == trailingslashit ( home_url() ) ) {
354 + if( $this->api_url == trailingslashit (home_url() ) ) {
458 355 return false; // Don't allow a plugin to ping itself
459 356 }
460 357
461 358 $api_params = array(
@@ -469,8 +366,9 @@
469 366 'url' => home_url(),
470 367 'beta' => ! empty( $data['beta'] ),
471 368 );
472 369
370 + $verify_ssl = $this->verify_ssl();
473 371 $request = wp_remote_post( $this->api_url, array( 'timeout' => 15, 'sslverify' => $verify_ssl, 'body' => $api_params ) );
474 372
475 373 if ( ! is_wp_error( $request ) ) {
476 374 $request = json_decode( wp_remote_retrieve_body( $request ) );
@@ -485,12 +383,8 @@
485 383 if ( $request && isset( $request->banners ) ) {
486 384 $request->banners = maybe_unserialize( $request->banners );
487 385 }
488 386
489 - if ( $request && isset( $request->icons ) ) {
490 - $request->icons = maybe_unserialize( $request->icons );
491 - }
492 -
493 387 if( ! empty( $request->sections ) ) {
494 388 foreach( $request->sections as $key => $section ) {
495 389 $request->$key = (array) $section;
496 390 }
@@ -498,11 +392,8 @@
498 392
499 393 return $request;
500 394 }
501 395
502 - /**
503 - * If available, show the changelog for sites in a multisite install.
504 - */
505 396 public function show_changelog() {
506 397
507 398 global $edd_plugin_data;
508 399
@@ -522,9 +413,11 @@
522 413 wp_die( __( 'You do not have permission to install plugin updates', 'polylang' ), __( 'Error', 'polylang' ), array( 'response' => 403 ) );
523 414 }
524 415
525 416 $data = $edd_plugin_data[ $_REQUEST['slug'] ];
526 - $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 );
527 420
528 421 if( false === $version_info ) {
529 422
530 423 $api_params = array(
@@ -543,8 +436,9 @@
543 436 if ( ! is_wp_error( $request ) ) {
544 437 $version_info = json_decode( wp_remote_retrieve_body( $request ) );
545 438 }
546 439
440 +
547 441 if ( ! empty( $version_info ) && isset( $version_info->sections ) ) {
548 442 $version_info->sections = maybe_unserialize( $version_info->sections );
549 443 } else {
550 444 $version_info = false;
@@ -555,30 +449,19 @@
555 449 $version_info->$key = (array) $section;
556 450 }
557 451 }
558 452
559 - $this->set_version_info_cache( $version_info );
453 + $this->set_version_info_cache( $version_info, $cache_key );
560 454
561 - // Delete the unneeded option
562 - delete_option( md5( 'edd_plugin_' . sanitize_key( $_REQUEST['plugin'] ) . '_' . $this->beta . '_version_info' ) );
563 455 }
564 456
565 - if ( isset( $version_info->sections ) ) {
566 - $sections = $this->convert_object_to_array( $version_info->sections );
567 - if ( ! empty( $sections['changelog'] ) ) {
568 - echo '<div style="background:#fff;padding:10px;">' . wp_kses_post( $sections['changelog'] ) . '</div>';
569 - }
457 + if( ! empty( $version_info ) && isset( $version_info->sections['changelog'] ) ) {
458 + echo '<div style="background:#fff;padding:10px;">' . $version_info->sections['changelog'] . '</div>';
570 459 }
571 460
572 461 exit;
573 462 }
574 463
575 - /**
576 - * Gets the plugin's cached version information from the database.
577 - *
578 - * @param string $cache_key
579 - * @return boolean|string
580 - */
581 464 public function get_cached_version_info( $cache_key = '' ) {
582 465
583 466 if( empty( $cache_key ) ) {
584 467 $cache_key = $this->cache_key;
@@ -589,24 +472,12 @@
589 472 if( empty( $cache['timeout'] ) || time() > $cache['timeout'] ) {
590 473 return false; // Cache is expired
591 474 }
592 475
593 - // We need to turn the icons into an array, thanks to WP Core forcing these into an object at some point.
594 - $cache['value'] = json_decode( $cache['value'] );
595 - if ( ! empty( $cache['value']->icons ) ) {
596 - $cache['value']->icons = (array) $cache['value']->icons;
597 - }
476 + return json_decode( $cache['value'] );
598 477
599 - return $cache['value'];
600 -
601 478 }
602 479
603 - /**
604 - * Adds the plugin version information to the database.
605 - *
606 - * @param string $value
607 - * @param string $cache_key
608 - */
609 480 public function set_version_info_cache( $value = '', $cache_key = '' ) {
610 481
611 482 if( empty( $cache_key ) ) {
612 483 $cache_key = $this->cache_key;
@@ -618,10 +489,8 @@
618 489 );
619 490
620 491 update_option( $cache_key, $data, 'no' );
621 492
622 - // Delete the duplicate option
623 - delete_option( 'edd_api_request_' . md5( serialize( $this->slug . $this->api_data['license'] . $this->beta ) ) );
624 493 }
625 494
626 495 /**
627 496 * Returns if the SSL of the store should be verified.
@@ -633,5 +502,4 @@
633 502 return (bool) apply_filters( 'edd_sl_api_request_verify_ssl', true, $this );
634 503 }
635 504
636 505 }
637 -