run:R W Run
DIR
2026-04-15 19:02:18
R W Run
DIR
2026-04-15 19:02:18
R W Run
DIR
2026-04-15 19:02:18
R W Run
761 By
2026-04-15 19:02:18
R W Run
3.3 KB
2026-04-15 19:02:18
R W Run
25.47 KB
2026-04-15 19:02:18
R W Run
10.69 KB
2026-04-15 19:02:18
R W Run
5.14 KB
2026-04-15 19:02:18
R W Run
16.87 KB
2026-04-15 19:02:18
R W Run
1.65 KB
2026-04-15 19:02:18
R W Run
6.16 KB
2026-04-15 19:02:18
R W Run
4.88 KB
2026-04-15 19:02:18
R W Run
1.31 KB
2026-04-15 19:02:18
R W Run
1.4 KB
2026-04-15 19:02:18
R W Run
15.24 KB
2026-04-15 19:02:18
R W Run
2.84 KB
2026-04-15 19:02:18
R W Run
5.5 KB
2026-04-15 19:02:18
R W Run
2 KB
2026-04-15 19:02:18
R W Run
3.28 KB
2026-04-15 19:02:18
R W Run
3.79 KB
2026-04-15 19:02:18
R W Run
2.1 KB
2026-04-15 19:02:18
R W Run
791 By
2026-04-15 19:02:18
R W Run
15.03 KB
2026-04-15 19:02:18
R W Run
6.5 KB
2026-04-15 19:02:18
R W Run
1.5 KB
2026-04-15 19:02:18
R W Run
8.61 KB
2026-04-15 19:02:18
R W Run
27.78 KB
2026-04-15 19:02:18
R W Run
2.03 KB
2026-04-15 19:02:18
R W Run
7.79 KB
2026-04-15 19:02:18
R W Run
9.9 KB
2026-04-15 19:02:18
R W Run
1.81 KB
2026-04-15 19:02:18
R W Run
7.42 KB
2026-04-15 19:02:18
R W Run
10.74 KB
2026-04-15 19:02:18
R W Run
1.28 KB
2026-04-15 19:02:18
R W Run
8.11 KB
2026-04-15 19:02:18
R W Run
1.79 KB
2026-04-15 19:02:18
R W Run
2.77 KB
2026-04-15 19:02:18
R W Run
780 By
2026-04-15 19:02:18
R W Run
5.37 KB
2026-04-15 19:02:18
R W Run
2.91 KB
2026-04-15 19:02:18
R W Run
794 By
2026-04-15 19:02:18
R W Run
3.69 KB
2026-04-15 19:02:18
R W Run
2.8 KB
2026-04-15 19:02:18
R W Run
37.06 KB
2026-04-15 19:02:18
R W Run
486 By
2026-04-15 19:02:18
R W Run
error_log
📄class-api.php
1<?php
2
3namespace WPaaS;
4
5use \WP_Error;
6
7if ( ! defined( 'ABSPATH' ) ) {
8
9 exit;
10
11}
12
13interface API_Interface {
14
15 public function get_disallowed_plugins();
16
17 public function is_valid_sso_hash( $hash );
18
19 public function user_changed_domain( $domain = '' );
20
21 public function get_woocommerce_products( $product_type );
22
23 public function refresh_blog_title( $blogname = null );
24
25 public function refresh_nextgen_compatibility( $is_nextgen_compat = false );
26
27 public function toggle_rum( $enabled = true );
28
29 public function flush_cdn();
30
31 public function get_failed_smart_updates();
32
33 public function smart_update_notice_dismiss( $dismiss_id );
34
35 public function hmt_register( $key );
36
37 public function get_experiment( $exp_name );
38
39}
40
41final class API implements API_Interface {
42
43 /**
44 * Return an array of disallowed plugins.
45 *
46 * Note: The transient used here is persistent, meaning it
47 * will not be short-circuited by object cache and it will
48 * always be set to a non-false value regardless of the API
49 * response.
50 *
51 * @return array
52 */
53 public function get_disallowed_plugins() {
54
55 $transient = Plugin::get_persistent_site_transient( 'gd_system_disallowed_plugins' );
56
57 if ( false !== $transient ) {
58
59 return (array) $transient;
60
61 }
62
63 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
64
65 $response = $this->call( 'disallowPlugins/' );
66
67 $body = json_decode( wp_remote_retrieve_body( $response ), true );
68 $disallowed_plugins = ! empty( $body['disallowPlugins'] ) ? (array) $body['disallowPlugins'] : [];
69
70 Plugin::set_persistent_site_transient( 'gd_system_disallowed_plugins', $disallowed_plugins, HOUR_IN_SECONDS );
71
72 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
73
74 return $disallowed_plugins;
75
76 }
77
78 /**
79 * Validate an SSO hash.
80 *
81 * @param string $hash
82 *
83 * @return bool
84 */
85 public function is_valid_sso_hash( $hash ) {
86
87 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
88 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
89
90 $method_args = [
91 'token' => $hash,
92 'database' => DB_NAME
93 ];
94
95 $response = $this->call(
96 "sso/allowLogin/",
97 $method_args,
98 'POST'
99 );
100
101 $body = json_decode( wp_remote_retrieve_body( $response ), true );
102
103 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
104 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
105
106 return isset( $body['allow'] ) ? $body['allow'] : false;
107
108 }
109
110 /**
111 * Check if a user has changed their domain.
112 *
113 * It isn't reflected here yet because we're waiting on the
114 * DNS TTL to take effect.
115 *
116 * Note: The transient used here is persistent, meaning it
117 * will not be short-circuited by object cache and it will
118 * always be set to a non-false value regardless of the API
119 * response.
120 *
121 * @param string $cname (optional)
122 *
123 * @return bool
124 */
125 public function user_changed_domain( $cname = '' ) {
126
127 $transient = Plugin::get_persistent_site_transient( 'gd_system_domain_changed' );
128
129 if ( false !== $transient ) {
130
131 return (
132 1 === (int) $transient
133 ||
134 'Y' === $transient // Back compat
135 );
136
137 }
138
139 $cname = ( $cname ) ? $cname : Plugin::domain();
140
141 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
142
143 $response = $this->call( 'domains/' . $cname );
144 $body = json_decode( wp_remote_retrieve_body( $response ), true );
145 $changed = ! empty( $body['domainChanged'] ) ? 1 : 0;
146 $timeout = 300;
147
148 Plugin::set_persistent_site_transient( 'gd_system_domain_changed', $changed, absint( $timeout ) );
149
150 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
151
152 return ( 1 === $changed );
153
154 }
155
156 /**
157 * Retreive WooCommerce product
158 *
159 * @param string $product_type The type of product to achieve.
160 *
161 * @return array $products The retreived products from the WooCommerce API.
162 */
163 public function get_woocommerce_products( $product_type ) {
164
165 $product_cache = get_transient( 'wpaas_woocommerce_' . $product_type );
166
167 if ( ! WP_DEBUG && false !== $product_cache ) {
168
169 return $product_cache;
170
171 }
172
173 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
174 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
175
176 $request = $this->call( $this->wp_public_api_accountuid( "automattic/%s/woocommerce/info" ) );
177
178 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
179 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
180
181 if ( 200 !== wp_remote_retrieve_response_code( $request ) || is_wp_error( $request ) ) {
182
183 set_transient( 'wpaas_woocommerce_' . $product_type, [], 15 * MINUTE_IN_SECONDS );
184
185 return [];
186
187 }
188
189 $products = json_decode( wp_remote_retrieve_body( $request ), true );
190
191 if ( empty( $products ) || ! is_array( $products ) || ! isset( $products['products'] ) ) {
192
193 set_transient( 'wpaas_woocommerce_' . $product_type, [], 15 * MINUTE_IN_SECONDS );
194
195 return [];
196
197 }
198
199 $type = 'extensions' === $product_type ? 'plugin' : 'theme';
200
201 // Return the proper product type only.
202 $products = array_filter(
203 $products['products'],
204 function ( $extension ) use ( $type ) {
205 return $type === $extension['type'];
206 }
207 );
208
209 set_transient( 'wpaas_woocommerce_' . $product_type, $products, 8 * HOUR_IN_SECONDS );
210
211 return $products;
212
213 }
214
215 /**
216 * Request that the API refresh its copy of the blog title.
217 *
218 * @param string $blogname (optional)
219 *
220 * @return void
221 */
222 public function refresh_blog_title( $blogname = null ) {
223
224 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
225 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
226 add_filter( 'wpaas_api_http_args', [ $this, 'non_blocking_http_args' ] );
227 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
228
229 $method_args = $blogname ? [ 'blogname' => htmlspecialchars_decode( $blogname, ENT_QUOTES ) ] : [];
230
231 $this->call( $this->wp_public_api_accountuid( "v3-proxy/%s/refreshBlogTitle" ), $method_args, 'POST' );
232
233 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
234 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
235 remove_filter( 'wpaas_api_http_args', [ $this, 'non_blocking_http_args' ] );
236 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
237
238 }
239
240 /**
241 * Request that the API refresh wether or not the site is nextgen compatible.
242 *
243 * @param boolean $is_nextgen_compat (optional)
244 *
245 * @return void
246 */
247 public function refresh_nextgen_compatibility( $is_nextgen_compat = false ) {
248
249 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
250 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
251 add_filter( 'wpaas_api_http_args', [ $this, 'non_blocking_http_args' ] );
252 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
253
254 $method_args = [ 'nextgenEnabled' => (bool) $is_nextgen_compat ];
255
256 $this->call( $this->wp_public_api_accountuid( "v3-proxy/%s/nextgen" ), $method_args, 'POST' );
257
258 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
259 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
260 remove_filter( 'wpaas_api_http_args', [ $this, 'non_blocking_http_args' ] );
261 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
262
263 }
264
265 /**
266 * Send RAD data to the API.
267 *
268 * @param string $name
269 * @param array $metadata (optional)
270 *
271 * @return void
272 */
273 public function log_rad_event( $name, $metadata = [] ) {
274
275 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
276 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
277 add_filter( 'wpaas_api_http_args', [ $this, 'non_blocking_http_args' ] );
278 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
279
280 $method_args = [
281 'datetime' => current_time( 'mysql', 1 ),
282 'metadata' => (array) $metadata,
283 'name' => $name,
284 ];
285
286
287 $this->call( $this->wp_public_api_accountuid( "rad/%s/event" ), $method_args, 'POST' );
288
289 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
290 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
291 remove_filter( 'wpaas_api_http_args', [ $this, 'non_blocking_http_args' ] );
292 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
293
294 }
295
296 /**
297 * Toggle RUM for this site.
298 *
299 * @param bool $enabled True or false
300 *
301 * @return void
302 */
303 public function toggle_rum( $enabled = true ) {
304
305 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
306 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
307 add_filter( 'wpaas_api_http_args', [ $this, 'non_blocking_http_args' ] );
308 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
309
310 $method_args = [
311 'rumEnabled' => (bool) $enabled,
312 ];
313
314 $this->call( $this->wp_public_api_accountuid( "v3-proxy/%s/rum" ), $method_args, 'POST' );
315
316 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
317 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
318 remove_filter( 'wpaas_api_http_args', [ $this, 'non_blocking_http_args' ] );
319 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
320
321 }
322
323 /**
324 * Flush full page cdn
325 *
326 *
327 * @return string|null
328 */
329 public function flush_cdn() {
330
331 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
332 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
333 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
334 try {
335 $response = $this->call( 'cdn/cache/' . $accountUid, [], 'DELETE' );
336 $body = json_decode( wp_remote_retrieve_body( $response ), true );
337 $invalidationId = ! empty( $body['invalidationId'] ) ? $body['invalidationId'] : null;
338 } catch ( WP_Error $e ) {
339 return null;
340 }
341
342 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
343 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
344
345 return $invalidationId;
346 }
347
348 /**
349 * Get CDN cache clear status
350 *
351 * @returns string|null
352 */
353 public function flush_cache_cdn_status( $invalidation_id ) {
354 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
355 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
356
357 try {
358 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
359 $response = $this->call( 'cdn/' . $accountUid . '/cache/' . $invalidation_id );
360 $body = json_decode( wp_remote_retrieve_body( $response ), true );
361 } catch ( WP_Error $e ) {
362 return null;
363 }
364
365 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
366 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
367
368 return $body;
369 }
370
371
372 /**
373 * Get feature flags
374 *
375 * @param string $api_url
376 *
377 * @returns array|null
378 */
379 public function fetch_feature_flag( $api_url ) {
380 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
381 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
382 add_filter( 'wpaas_api_http_args', [ $this, 'timeout_3s_http_args' ] );
383
384 /** Logg user action */
385 $GLOBALS['wpaas_activity_logger']->log_sp_action( get_current_user_id(), 'Fetch feature flags from API' );
386
387 try {
388 $response = $this->call( $api_url );
389 $body = json_decode( wp_remote_retrieve_body( $response ), true );
390 } catch ( WP_Error $e ) {
391 return null;
392 }
393
394 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
395 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
396 remove_filter( 'wpaas_api_http_args', [ $this, 'timeout_3s_http_args' ] );
397
398 return $body;
399 }
400
401 /**
402 * Filter the API URL when using the V3 API.
403 *
404 * @param string $api_url
405 *
406 * @return string
407 */
408 public function v3_api_url( $api_url ) {
409
410 if ( ! defined( 'GD_ACCOUNT_UID' ) || ! GD_ACCOUNT_UID ) {
411
412 return;
413
414 }
415
416 $env = Plugin::get_env();
417 $prefix = ( 'prod' === $env ) ? '' : "{$env}-";
418
419 return sprintf(
420 "https://mwp.api.phx3.{$prefix}godaddy.com/api/v1/mwp/sites/%s/",
421 GD_ACCOUNT_UID
422 );
423
424 }
425
426 /**
427 * Filter the API URL when using the WP Public API.
428 *
429 * @return string
430 */
431 public function wp_public_api_url() {
432
433 $env = Plugin::get_env();
434
435 if ( in_array( $env, array( 'myh.test' ) ) ) {
436 $env = 'test';
437 }
438
439 if ( in_array( $env, [ 'dev', 'test' ], true ) ) {
440 return "https://wp-api.wpsecurity.{$env}-godaddy.com/api/v1/";
441 }
442
443 return "https://wp-api.wpsecurity.godaddy.com/api/v1/";
444 }
445
446 /**
447 * Filter the HTTP request args when using the V3 API.
448 *
449 * @param array $http_args
450 *
451 * @return array
452 */
453 public function v3_api_http_args( $http_args ) {
454 $body = apply_filters( 'wpaas_v3_api_body_signage', [] );
455
456 $http_args['headers'] = array_merge( $http_args['headers'], Plugin::sign_http_request( wp_json_encode( $body ) ) );
457
458 return $http_args;
459
460 }
461
462
463 /**
464 * Filter the HTTP request args to use a 30s timeout.
465 *
466 * @param array $http_args
467 *
468 * @return array
469 */
470 public function timeout_30s_http_args( $http_args ) {
471
472 $http_args['timeout'] = 30;
473
474 return $http_args;
475
476 }
477
478 /**
479 * Filter the HTTP request args to use a 3s timeout.
480 *
481 * @param array $http_args
482 *
483 * @return array
484 */
485 public function timeout_3s_http_args( $http_args ) {
486
487 $http_args['timeout'] = 3;
488
489 return $http_args;
490
491 }
492
493 /**
494 * Filter the HTTP request args to make calls non-blocking.
495 *
496 * @param array $http_args
497 *
498 * @return array
499 */
500 public function non_blocking_http_args( $http_args ) {
501
502 $http_args['blocking'] = false;
503 $http_args['timeout'] = 5;
504
505 return $http_args;
506
507 }
508
509 /**
510 * Make an API call.
511 *
512 * @param string $method
513 * @param array|string $method_args (optional)
514 * @param string $http_verb (optional)
515 *
516 * @return array|WP_Error
517 */
518 private function call( $method, $method_args = [], $http_verb = 'GET' ) {
519
520 $api_url = (string) apply_filters( 'wpaas_api_url', '' );
521 if ( ! $api_url ) {
522 /** Logg user action */
523 $GLOBALS['wpaas_activity_logger']->log_sp_action( get_current_user_id(), sprintf( 'API call fail URL: %s', $api_url ) );
524
525 return new WP_Error( 'wpaas_api_url_not_found' );
526
527 }
528
529 add_filter( 'wpaas_v3_api_body_signage', function () use ( $method_args ) {
530 return $method_args;
531 } );
532
533 $http_args = (array) apply_filters(
534 'wpaas_api_http_args',
535 [
536 'headers' => [
537 'Content-Type' => 'application/json',
538 ],
539 ]
540 );
541
542 $url = trailingslashit( $api_url ) . $method;
543
544 $retries = 0;
545 $max_retries = 1;
546
547 add_filter( 'https_ssl_verify', '__return_false' );
548
549 while ( $retries <= $max_retries ) {
550
551 $retries ++;
552
553 switch ( $http_verb ) {
554
555 case 'GET':
556 if ( ! empty( $method_args ) ) {
557
558 $url .= '?' . build_query( $method_args );
559
560 }
561
562 $response = Plugin::remote_get( $url, $http_args );
563 break;
564
565 case 'POST':
566 $http_args['body'] = (bool) apply_filters( 'wpaas_api_http_post_body_json', false ) ? json_encode( $method_args, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) : $method_args;
567
568 $response = Plugin::remote_post( $url, $http_args );
569
570 break;
571 case "DELETE":
572 $http_args['body'] = (bool) apply_filters( 'wpaas_api_http_post_body_json', false ) ? json_encode( $method_args, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) : $method_args;
573 $response = Plugin::remote_request( $url, array_merge( $http_args, [
574 'method' => 'DELETE'
575 ] ) );
576 break;
577
578 default:
579 return new WP_Error( 'wpaas_api_invalid_http_verb' );
580
581 }
582
583 $response_code = wp_remote_retrieve_response_code( $response );
584
585 // Check if we aren't on the last iteration and we can try the request again
586 if (
587 $retries <= $max_retries
588 &&
589 $this->is_retryable( $response, $response_code )
590 ) {
591
592 // Give some time for the API to recover
593 sleep( (int) apply_filters( 'wpaas_api_retry_delay', 1 ) );
594
595 continue;
596
597 }
598
599 break;
600
601 }
602
603 remove_filter( 'https_ssl_verify', '__return_false' );
604
605 if ( 200 !== $response_code && 204 !== $response_code ) {
606 /** Logg user action */
607 $GLOBALS['wpaas_activity_logger']->log_sp_action( get_current_user_id(),
608 sprintf( 'API call fail URL: %s status_code: %s', $url, $response_code )
609 );
610
611 return new WP_Error( 'wpaas_api_bad_status', $response_code );
612
613 }
614
615 /** Logg user action */
616 $GLOBALS['wpaas_activity_logger']->log_sp_action( get_current_user_id(),
617 sprintf( 'API call success URL: %s status_code: %s', $url, $response_code )
618 );
619
620 return $response;
621
622 }
623
624 /**
625 * Check if a response is an error and retryable.
626 *
627 * @param array|WP_Error $response
628 * @param int $response_code
629 *
630 * @return bool
631 */
632 private function is_retryable( $response, $response_code ) {
633
634 if ( 200 === $response_code ) {
635
636 return false;
637
638 }
639
640 $body = json_decode( wp_remote_retrieve_body( $response ), true );
641
642 if (
643 isset( $body['status'], $body['type'], $body['code'] )
644 &&
645 503 === absint( $body['status'] )
646 &&
647 'error' === $body['type']
648 &&
649 'RetryRequest' === $body['code']
650 ) {
651
652 return true;
653
654 }
655
656 return false;
657
658 }
659
660 public function get_failed_smart_updates() {
661
662 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
663 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
664
665 $response = $this->call( 'smart-updates' );
666
667 if ( is_wp_error( $response ) ) {
668 return [];
669 }
670
671 $body = json_decode( wp_remote_retrieve_body( $response ), true );
672
673 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
674 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
675
676 return $body;
677 }
678
679 public function get_trusted_site_sso_url() {
680
681 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
682 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
683
684 $response = $this->call( $this->wp_public_api_accountuid( "v3-proxy/%s/trustedsite" ) );
685
686 if ( is_wp_error( $response ) ) {
687 return [];
688 }
689
690 $body = json_decode( wp_remote_retrieve_body( $response ), true );
691
692 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
693 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
694
695 return $body;
696 }
697
698 public function smart_update_notice_dismiss( $dismiss_id ) {
699
700 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
701 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
702 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
703
704 $response = $this->call( 'smart-updates/dismiss', [ 'dismissId' => $dismiss_id ], 'POST' );
705
706 if ( is_wp_error( $response ) ) {
707 return false;
708 }
709
710 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
711 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
712 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
713
714 return true;
715 }
716
717 public function hmt_register( $key ) {
718
719 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
720 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
721 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
722
723 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
724
725 $data = [
726 'mwp_potential_key' => $key
727 ];
728 try {
729 $response = $this->call( 'backup/' . $accountUid . '/register', $data, 'POST' );
730 $body = json_decode( wp_remote_retrieve_body( $response ), true );
731 $success = ! empty( $body['success'] ) ? $body['success'] : null;
732 } catch ( WP_Error $e ) {
733 return null;
734 }
735
736 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
737 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
738 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
739
740 return $success;
741 }
742
743 private function wp_public_api_accountuid( $path ) {
744
745 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
746
747 return sprintf(
748 $path,
749 $accountUid
750 );
751
752 }
753
754 /**
755 * Fetch an experiment result from the WP Public API.
756 *
757 * @param string $exp_name The experiment name to query.
758 *
759 * @return bool|null True if experiment should show, false if not, null on failure.
760 */
761 public function get_experiment( $exp_name ) {
762
763 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
764 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
765 add_filter( 'wpaas_api_http_args', [ $this, 'timeout_3s_http_args' ] );
766
767 try {
768 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
769 $response = $this->call( 'experiment/' . $accountUid, [ 'exp_name' => $exp_name ] );
770 $body = json_decode( wp_remote_retrieve_body( $response ), true );
771
772 return ! empty( $body['show'] );
773 } catch ( WP_Error $e ) {
774 return null;
775 } finally {
776 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
777 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
778 remove_filter( 'wpaas_api_http_args', [ $this, 'timeout_3s_http_args' ] );
779 }
780
781 }
782
783 public function show_nps_form($npsFormId) {
784 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
785 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
786
787 try {
788 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
789 $response = $this->call( 'feedback-api-proxy/' . $accountUid . '/' . rawurlencode($npsFormId) . '/show');
790 $body = json_decode( wp_remote_retrieve_body( $response ), true );
791 return $body['show'];
792 } catch ( WP_Error $e ) {
793 return null;
794 } finally {
795 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
796 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
797 }
798 }
799
800 public function get_nps_form_configuration($nps_form_id) {
801 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
802 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
803
804 try {
805 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
806 $response = $this->call( 'feedback-api-proxy/' . $accountUid . '/' . rawurlencode($nps_form_id) . '/form-configuration');
807
808 // Validate response before processing
809 if ( 200 !== wp_remote_retrieve_response_code( $response ) || is_wp_error( $response ) ) {
810 return null;
811 }
812
813 $body = json_decode( wp_remote_retrieve_body( $response ), true );
814
815 return $body['config'];
816 } catch ( \Exception $e ) {
817 return null;
818 } finally {
819 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
820 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
821 }
822
823 return null;
824 }
825
826 public function nps_form_submit($form_data, $nps_form_id) {
827 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
828 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
829 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
830
831 try {
832 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
833
834 $data = [
835 'accountUid' => $accountUid,
836 'feedbackId' => $nps_form_id,
837 'data' => $form_data
838 ];
839
840 $this->call( 'feedback-api-proxy/nps-submit', $data, 'POST' );
841 } catch ( WP_Error $e ) {
842 return null;
843 }
844 $nps_option_name = 'wpaas_nps_form_%s';
845
846 $option_name = sprintf( $nps_option_name, GD_ACCOUNT_UID );
847
848 $cached_data = [
849 'show_form' => false,
850 'timestamp' => time()
851 ];
852
853 update_option( $option_name, $cached_data );
854
855 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
856 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
857 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
858
859 return true;
860 }
861
862 public function nps_form_dismiss($nps_form_id) {
863 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
864 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
865 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
866
867 try {
868 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
869 $data = [
870 'accountUid' => $accountUid,
871 'feedbackId' => $nps_form_id
872 ];
873
874 $response = $this->call( 'feedback-api-proxy/nps/dismiss', $data, 'POST' );
875 json_decode( wp_remote_retrieve_body( $response ), true );
876 } catch ( WP_Error $e ) {
877 return null;
878 }
879 $nps_option_name = 'wpaas_nps_form_%s';
880
881 $option_name = sprintf( $nps_option_name, GD_ACCOUNT_UID );
882
883 $cached_data = [
884 'show_form' => false,
885 'timestamp' => time()
886 ];
887
888 update_option( $option_name, $cached_data );
889
890 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
891 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
892 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
893
894 return true;
895 }
896 public function feedback_form_submit ($form_data, $feedback_form_id) {
897 add_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
898 add_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
899 add_filter( 'wpaas_api_http_post_body_json', '__return_true' );
900
901 try {
902 $accountUid = defined( 'GD_ACCOUNT_UID' ) ? GD_ACCOUNT_UID : '';
903
904 $data = [
905 'accountUid' => $accountUid,
906 'feedbackId' => $feedback_form_id,
907 'data' => $form_data
908 ];
909
910 $this->call( 'feedback-api-proxy/submit', $data, 'POST' );
911 } catch ( WP_Error $e ) {
912 return null;
913 }
914
915 remove_filter( 'wpaas_api_url', [ $this, 'wp_public_api_url' ] );
916 remove_filter( 'wpaas_api_http_args', [ $this, 'v3_api_http_args' ] );
917 remove_filter( 'wpaas_api_http_post_body_json', '__return_true' );
918
919 return true;
920 }
921}
922