PluginProbe
WPIDE – File Manager & Code Editor / 3.4.1
WPIDE – File Manager & Code Editor v3.4.1
3.5.10 3.5.9 3.5.8 3.5.7 2.0.14 2.0.15 2.0.16 2.0.2 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1 2.2 2.3 2.3.1 2.3.2 2.4.0 2.5 2.6 3.0 3.1 3.2 All 56 releases
← All changes | freemius/includes/class-fs-api.php +125 -185 3.5.9 → 3.4.1 View file →
@@ -64,16 +64,8 @@
64 64 */
65 65 private $_sdk_version;
66 66
67 67 /**
68 - * @author Leo Fajardo (@leorw)
69 - * @since 2.5.0
70 - *
71 - * @var string
72 - */
73 - private $_url;
74 -
75 - /**
76 68 * @param string $slug
77 69 * @param string $scope 'app', 'developer', 'user' or 'install'.
78 70 * @param number $id Element's id.
79 71 * @param string $public_key Public key.
@@ -79,9 +71,8 @@
79 71 * @param string $public_key Public key.
80 72 * @param bool $is_sandbox
81 73 * @param bool|string $secret_key Element's secret key.
82 74 * @param null|string $sdk_version
83 - * @param null|string $url
84 75 *
85 76 * @return FS_Api
86 77 */
87 78 static function instance(
@@ -90,10 +81,9 @@
90 81 $id,
91 82 $public_key,
92 83 $is_sandbox,
93 84 $secret_key = false,
94 - $sdk_version = null,
95 - $url = null
85 + $sdk_version = null
96 86 ) {
97 87 $identifier = md5( $slug . $scope . $id . $public_key . ( is_string( $secret_key ) ? $secret_key : '' ) . json_encode( $is_sandbox ) );
98 88
99 89 if ( ! isset( self::$_instances[ $identifier ] ) ) {
@@ -98,9 +88,9 @@
98 88
99 89 if ( ! isset( self::$_instances[ $identifier ] ) ) {
100 90 self::_init();
101 91
102 - self::$_instances[ $identifier ] = new FS_Api( $slug, $scope, $id, $public_key, $secret_key, $is_sandbox, $sdk_version, $url );
92 + self::$_instances[ $identifier ] = new FS_Api( $slug, $scope, $id, $public_key, $secret_key, $is_sandbox, $sdk_version );
103 93 }
104 94
105 95 return self::$_instances[ $identifier ];
106 96 }
@@ -132,9 +122,8 @@
132 122 * @param string $public_key Public key.
133 123 * @param bool|string $secret_key Element's secret key.
134 124 * @param bool $is_sandbox
135 125 * @param null|string $sdk_version
136 - * @param null|string $url
137 126 */
138 127 private function __construct(
139 128 $slug,
140 129 $scope,
@@ -141,16 +130,14 @@
141 130 $id,
142 131 $public_key,
143 132 $secret_key,
144 133 $is_sandbox,
145 - $sdk_version,
146 - $url
134 + $sdk_version
147 135 ) {
148 136 $this->_api = new Freemius_Api_WordPress( $scope, $id, $public_key, $secret_key, $is_sandbox );
149 137
150 138 $this->_slug = $slug;
151 139 $this->_sdk_version = $sdk_version;
152 - $this->_url = $url;
153 140 $this->_logger = FS_Logger::get_logger( WP_FS__SLUG . '_' . $slug . '_api', WP_FS__DEBUG_SDK, WP_FS__ECHO_DEBUG_SDK );
154 141 }
155 142
156 143 /**
@@ -188,17 +175,15 @@
188 175 *
189 176 * @param string $path
190 177 * @param string $method
191 178 * @param array $params
192 - * @param bool $in_retry Is in retry or first call attempt.
179 + * @param bool $retry Is in retry or first call attempt.
193 180 *
194 181 * @return array|mixed|string|void
195 182 */
196 - private function _call( $path, $method = 'GET', $params = array(), $in_retry = false ) {
183 + private function _call( $path, $method = 'GET', $params = array(), $retry = false ) {
197 184 $this->_logger->entrance( $method . ':' . $path );
198 185
199 - $force_http = ( ! $in_retry && self::$_options->get_option( 'api_force_http', false ) );
200 -
201 186 if ( self::is_temporary_down() ) {
202 187 $result = $this->get_temporary_unavailable_error();
203 188 } else {
204 189 /**
@@ -212,30 +197,16 @@
212 197 $path = add_query_arg( 'sdk_version', $this->_sdk_version, $path );
213 198 }
214 199 }
215 200
216 - /**
217 - * @since 2.5.0 Include the site's URL, if available, in all API requests that are going through the API manager.
218 - */
219 - if ( ! empty( $this->_url ) ) {
220 - if ( false === strpos( $path, 'url=' ) &&
221 - ! isset( $params['url'] )
222 - ) {
223 - $path = add_query_arg( 'url', $this->_url, $path );
224 - }
225 - }
226 -
227 201 $result = $this->_api->Api( $path, $method, $params );
228 202
229 - if (
230 - ! $in_retry &&
231 - null !== $result &&
232 - isset( $result->error ) &&
233 - isset( $result->error->code )
203 + if ( null !== $result &&
204 + isset( $result->error ) &&
205 + isset( $result->error->code ) &&
206 + 'request_expired' === $result->error->code
234 207 ) {
235 - $retry = false;
236 -
237 - if ( 'request_expired' === $result->error->code ) {
208 + if ( ! $retry ) {
238 209 $diff = isset( $result->error->timestamp ) ?
239 210 ( time() - strtotime( $result->error->timestamp ) ) :
240 211 false;
241 212
@@ -241,37 +212,17 @@
241 212
242 213 // Try to sync clock diff.
243 214 if ( false !== $this->_sync_clock_diff( $diff ) ) {
244 215 // Retry call with new synced clock.
245 - $retry = true;
216 + return $this->_call( $path, $method, $params, true );
246 217 }
247 - } else if (
248 - Freemius_Api_WordPress::IsHttps() &&
249 - FS_Api::is_ssl_error_response( $result )
250 - ) {
251 - $force_http = true;
252 - $retry = true;
253 218 }
254 -
255 - if ( $retry ) {
256 - if ( $force_http ) {
257 - $this->toggle_force_http( true );
258 - }
259 -
260 - $result = $this->_call( $path, $method, $params, true );
261 - }
262 219 }
263 220 }
264 221
265 - if ( self::is_api_error( $result ) ) {
266 - if ( $this->_logger->is_on() ) {
267 - // Log API errors.
268 - $this->_logger->api_error( $result );
269 - }
270 -
271 - if ( $force_http ) {
272 - $this->toggle_force_http( false );
273 - }
222 + if ( $this->_logger->is_on() && self::is_api_error( $result ) ) {
223 + // Log API errors.
224 + $this->_logger->api_error( $result );
274 225 }
275 226
276 227 return $result;
277 228 }
@@ -317,14 +268,11 @@
317 268 if ( WP_FS__DEV_MODE || $this->_api->IsSandbox() ) {
318 269 $flush = true;
319 270 }
320 271
321 - $has_valid_cache = self::$_cache->has_valid( $cache_key, $expiration );
322 - $cached_result = $has_valid_cache ?
323 - self::$_cache->get( $cache_key ) :
324 - null;
272 + $cached_result = self::$_cache->get( $cache_key );
325 273
326 - if ( $flush || is_null( $cached_result ) ) {
274 + if ( $flush || ! self::$_cache->has_valid( $cache_key, $expiration ) ) {
327 275 $result = $this->call( $path );
328 276
329 277 if ( ! is_object( $result ) || isset( $result->error ) ) {
330 278 // Api returned an error.
@@ -354,11 +302,9 @@
354 302 }
355 303 }
356 304 }
357 305
358 - if ( is_numeric( $expiration ) ) {
359 - self::$_cache->set( $cache_key, $result, $expiration );
360 - }
306 + self::$_cache->set( $cache_key, $result, $expiration );
361 307
362 308 $cached_result = $result;
363 309 } else {
364 310 $this->_logger->log( 'Using cached API result.' );
@@ -366,45 +312,8 @@
366 312
367 313 return $cached_result;
368 314 }
369 315
370 - /**
371 - * @todo Remove this method after migrating Freemius::safe_remote_post() to FS_Api::call().
372 - *
373 - * @author Leo Fajardo (@leorw)
374 - * @since 2.5.4
375 - *
376 - * @param string $url
377 - * @param array $remote_args
378 - *
379 - * @return array|WP_Error The response array or a WP_Error on failure.
380 - */
381 - static function remote_request( $url, $remote_args ) {
382 - if ( ! class_exists( 'Freemius_Api_WordPress' ) ) {
383 - require_once WP_FS__DIR_SDK . '/FreemiusWordPress.php';
384 - }
385 -
386 - if ( method_exists( 'Freemius_Api_WordPress', 'RemoteRequest' ) ) {
387 - return Freemius_Api_WordPress::RemoteRequest( $url, $remote_args );
388 - }
389 -
390 - // The following is for backward compatibility when a modified PHP SDK version is in use and the `Freemius_Api_WordPress:RemoteRequest()` method doesn't exist.
391 - $response = wp_remote_request( $url, $remote_args );
392 -
393 - if (
394 - is_array( $response ) &&
395 - (
396 - empty( $response['headers'] ) ||
397 - empty( $response['headers']['x-api-server'] )
398 - )
399 - ) {
400 - // API is considered blocked if the response doesn't include the `x-api-server` header. When there's no error but this header doesn't exist, the response is usually not in the expected form (e.g., cannot be JSON-decoded).
401 - $response = new WP_Error( 'api_blocked', htmlentities( $response['body'] ) );
402 - }
403 -
404 - return $response;
405 - }
406 -
407 316 /**
408 317 * Check if there's a cached version of the API request.
409 318 *
410 319 * @author Vova Feldman (@svovaf)
@@ -473,40 +382,53 @@
473 382 // return $method . '_' . array_pop($exploded) . '_' . md5($canonized . json_encode($params));
474 383 return strtolower( $method . ':' . $canonized ) . ( ! empty( $params ) ? '#' . md5( json_encode( $params ) ) : '' );
475 384 }
476 385
477 - /**
478 - * @author Leo Fajardo (@leorw)
479 - * @since 2.5.4
480 - *
481 - * @param bool $is_http
482 - */
483 - private function toggle_force_http( $is_http ) {
484 - self::$_options->set_option( 'api_force_http', $is_http, true );
386 + /**
387 + * Test API connectivity.
388 + *
389 + * @author Vova Feldman (@svovaf)
390 + * @since 1.0.9 If fails, try to fallback to HTTP.
391 + * @since 1.1.6 Added a 5-min caching mechanism, to prevent from overloading the server if the API if
392 + * temporary down.
393 + *
394 + * @return bool True if successful connectivity to the API.
395 + */
396 + static function test() {
397 + self::_init();
485 398
486 - if ( $is_http ) {
487 - Freemius_Api_WordPress::SetHttp();
488 - } else if ( method_exists( 'Freemius_Api_WordPress', 'SetHttps' ) ) {
489 - Freemius_Api_WordPress::SetHttps();
490 - }
491 - }
399 + $cache_key = 'ping_test';
492 400
493 - /**
494 - * @author Leo Fajardo (@leorw)
495 - * @since 2.5.4
496 - *
497 - * @param mixed $response
498 - *
499 - * @return bool
500 - */
501 - static function is_blocked( $response ) {
502 - return (
503 - self::is_api_error_object( $response, true ) &&
504 - isset( $response->error->code ) &&
505 - 'api_blocked' === $response->error->code
506 - );
507 - }
401 + $test = self::$_cache->get_valid( $cache_key, null );
508 402
403 + if ( is_null( $test ) ) {
404 + $test = Freemius_Api_WordPress::Test();
405 +
406 + if ( false === $test && Freemius_Api_WordPress::IsHttps() ) {
407 + // Fallback to HTTP, since HTTPS fails.
408 + Freemius_Api_WordPress::SetHttp();
409 +
410 + self::$_options->set_option( 'api_force_http', true, true );
411 +
412 + $test = Freemius_Api_WordPress::Test();
413 +
414 + if ( false === $test ) {
415 + /**
416 + * API connectivity test fail also in HTTP request, therefore,
417 + * fallback to HTTPS to keep connection secure.
418 + *
419 + * @since 1.1.6
420 + */
421 + self::$_options->set_option( 'api_force_http', false, true );
422 + }
423 + }
424 +
425 + self::$_cache->set( $cache_key, $test, WP_FS__TIME_5_MIN_IN_SEC );
426 + }
427 +
428 + return $test;
429 + }
430 +
509 431 /**
510 432 * Check if API is temporary down.
511 433 *
512 434 * @author Vova Feldman (@svovaf)
@@ -539,8 +461,58 @@
539 461 );
540 462 }
541 463
542 464 /**
465 + * Ping API for connectivity test, and return result object.
466 + *
467 + * @author Vova Feldman (@svovaf)
468 + * @since 1.0.9
469 + *
470 + * @param null|string $unique_anonymous_id
471 + * @param array $params
472 + *
473 + * @return object
474 + */
475 + function ping( $unique_anonymous_id = null, $params = array() ) {
476 + $this->_logger->entrance();
477 +
478 + if ( self::is_temporary_down() ) {
479 + return $this->get_temporary_unavailable_error();
480 + }
481 +
482 + $pong = is_null( $unique_anonymous_id ) ?
483 + Freemius_Api_WordPress::Ping() :
484 + $this->_call( 'ping.json?' . http_build_query( array_merge(
485 + array( 'uid' => $unique_anonymous_id ),
486 + $params
487 + ) ) );
488 +
489 + if ( $this->is_valid_ping( $pong ) ) {
490 + return $pong;
491 + }
492 +
493 + if ( self::should_try_with_http( $pong ) ) {
494 + // Fallback to HTTP, since HTTPS fails.
495 + Freemius_Api_WordPress::SetHttp();
496 +
497 + self::$_options->set_option( 'api_force_http', true, true );
498 +
499 + $pong = is_null( $unique_anonymous_id ) ?
500 + Freemius_Api_WordPress::Ping() :
501 + $this->_call( 'ping.json?' . http_build_query( array_merge(
502 + array( 'uid' => $unique_anonymous_id ),
503 + $params
504 + ) ) );
505 +
506 + if ( ! $this->is_valid_ping( $pong ) ) {
507 + self::$_options->set_option( 'api_force_http', false, true );
508 + }
509 + }
510 +
511 + return $pong;
512 + }
513 +
514 + /**
543 515 * Check if based on the API result we should try
544 516 * to re-run the same request with HTTP instead of HTTPS.
545 517 *
546 518 * @author Vova Feldman (@svovaf)
@@ -567,8 +539,22 @@
567 539 ) ) );
568 540
569 541 }
570 542
543 + /**
544 + * Check if valid ping request result.
545 + *
546 + * @author Vova Feldman (@svovaf)
547 + * @since 1.1.1
548 + *
549 + * @param mixed $pong
550 + *
551 + * @return bool
552 + */
553 + function is_valid_ping( $pong ) {
554 + return Freemius_Api_WordPress::Test( $pong );
555 + }
556 +
571 557 function get_url( $path = '' ) {
572 558 return Freemius_Api_WordPress::GetUrl( $path, $this->_api->IsSandbox() );
573 559 }
574 560
@@ -584,16 +570,8 @@
584 570 self::$_cache = FS_Cache_Manager::get_manager( WP_FS__API_CACHE_OPTION_NAME );
585 571 self::$_cache->clear();
586 572 }
587 573
588 - /**
589 - * @author Leo Fajardo (@leorw)
590 - * @since 2.5.4
591 - */
592 - static function clear_force_http_flag() {
593 - self::$_options->unset_option( 'api_force_http' );
594 - }
595 -
596 574 #----------------------------------------------------------------------------------
597 575 #region Error Handling
598 576 #----------------------------------------------------------------------------------
599 577
@@ -614,54 +592,16 @@
614 592 * @author Vova Feldman (@svovaf)
615 593 * @since 2.0.0
616 594 *
617 595 * @param mixed $result
618 - * @param bool $ignore_message
619 596 *
620 597 * @return bool Is API result contains an error.
621 598 */
622 - static function is_api_error_object( $result, $ignore_message = false ) {
599 + static function is_api_error_object( $result ) {
623 600 return (
624 601 is_object( $result ) &&
625 602 isset( $result->error ) &&
626 - ( $ignore_message || isset( $result->error->message ) )
627 - );
628 - }
629 -
630 - /**
631 - * @author Leo Fajardo (@leorw)
632 - * @since 2.5.4
633 - *
634 - * @param WP_Error|object|string $response
635 - *
636 - * @return bool
637 - */
638 - static function is_ssl_error_response( $response ) {
639 - $http_error = null;
640 -
641 - if ( $response instanceof WP_Error ) {
642 - if (
643 - isset( $response->errors ) &&
644 - isset( $response->errors['http_request_failed'] )
645 - ) {
646 - $http_error = strtolower( $response->errors['http_request_failed'][0] );
647 - }
648 - } else if (
649 - self::is_api_error_object( $response ) &&
650 - ! empty( $response->error->message )
651 - ) {
652 - $http_error = $response->error->message;
653 - }
654 -
655 - return (
656 - ! empty( $http_error ) &&
657 - (
658 - false !== strpos( $http_error, 'curl error 35' ) ||
659 - (
660 - false === strpos( $http_error, '</html>' ) &&
661 - false !== strpos( $http_error, 'ssl' )
662 - )
663 - )
603 + isset( $result->error->message )
664 604 );
665 605 }
666 606
667 607 /**