PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.5.6
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.5.6
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / classes / models / FrmAddon.php

FrmAddon.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 5.5.6, at classes/models/FrmAddon.php

717 lines 21.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 /** @phpstan-consistent-constructor */
7 class FrmAddon {
8 public $store_url = 'https://formidableforms.com';
9 public $download_id;
10 public $plugin_file;
11 public $plugin_folder;
12 public $plugin_name;
13 public $plugin_slug;
14 public $option_name;
15 public $version;
16 public $author = 'Strategy11';
17 public $is_parent_licence = false;
18 public $needs_license = true;
19 private $is_expired_addon = false;
20 public $license;
21 protected $get_beta = false;
22
23 public function __construct() {
24
25 if ( empty( $this->plugin_slug ) ) {
26 $this->plugin_slug = preg_replace( '/[^a-zA-Z0-9_\s]/', '', str_replace( ' ', '_', strtolower( $this->plugin_name ) ) );
27 }
28 if ( empty( $this->option_name ) ) {
29 $this->option_name = 'edd_' . $this->plugin_slug . '_license_';
30 }
31
32 $this->plugin_folder = plugin_basename( $this->plugin_file );
33 $this->license = $this->get_license();
34
35 add_filter( 'frm_installed_addons', array( &$this, 'insert_installed_addon' ) );
36 $this->edd_plugin_updater();
37 }
38
39 public static function load_hooks() {
40 add_filter( 'frm_include_addon_page', '__return_true' );
41 new static();
42 }
43
44 public function insert_installed_addon( $plugins ) {
45 $plugins[ $this->plugin_slug ] = $this;
46
47 return $plugins;
48 }
49
50 public static function get_addon( $plugin_slug ) {
51 $plugins = apply_filters( 'frm_installed_addons', array() );
52 $plugin = false;
53 if ( isset( $plugins[ $plugin_slug ] ) ) {
54 $plugin = $plugins[ $plugin_slug ];
55 }
56
57 return $plugin;
58 }
59
60 public function edd_plugin_updater() {
61
62 $this->is_license_revoked();
63 $license = $this->license;
64
65 add_action( 'after_plugin_row_' . plugin_basename( $this->plugin_file ), array( $this, 'maybe_show_license_message' ), 10, 2 );
66
67 if ( ! empty( $license ) ) {
68
69 if ( 'formidable/formidable.php' !== $this->plugin_folder ) {
70 add_filter( 'plugins_api', array( &$this, 'plugins_api_filter' ), 10, 3 );
71 }
72
73 add_filter( 'site_transient_update_plugins', array( &$this, 'clear_expired_download' ) );
74 }
75 }
76
77 /**
78 * Updates information on the "View version x.x details" page with custom data.
79 *
80 * @uses api_request()
81 *
82 * @param mixed $_data
83 * @param string $_action
84 * @param object $_args
85 *
86 * @return object $_data
87 */
88 public function plugins_api_filter( $_data, $_action = '', $_args = null ) {
89
90 if ( $_action != 'plugin_information' ) {
91 return $_data;
92 }
93
94 $slug = basename( $this->plugin_file, '.php' );
95 $slug2 = str_replace( '/' . $slug . '.php', '', $this->plugin_folder );
96 if ( empty( $_args->slug ) || ( $_args->slug != $slug && $_args->slug !== $slug2 ) ) {
97 return $_data;
98 }
99
100 $item_id = $this->download_id;
101 if ( empty( $item_id ) ) {
102 $_data = array(
103 'name' => $this->plugin_name,
104 'excerpt' => '',
105 'changelog' => 'See the full changelog at <a href="' . esc_url( $this->store_url . '/changelog/' ) . '"></a>',
106 'banners' => array(
107 'high' => '',
108 'low' => 'https://ps.w.org/formidable/assets/banner-1544x500.png',
109 ),
110 );
111 } else {
112 $api = new FrmFormApi( $this->license );
113 $plugins = $api->get_api_info();
114 $_data = $plugins[ $item_id ];
115 }
116
117 $_data['sections'] = array(
118 'description' => $_data['excerpt'],
119 'changelog' => $_data['changelog'],
120 );
121 $_data['author'] = '<a href="' . esc_url( $this->store_url ) . '">' . esc_html( $this->author ) . '</a>';
122 $_data['homepage'] = $this->store_url;
123
124 return (object) $_data;
125 }
126
127 public function get_license() {
128 $license = $this->maybe_get_pro_license();
129 if ( ! empty( $license ) ) {
130 return $license;
131 }
132
133 $license = trim( get_option( $this->option_name . 'key' ) );
134 if ( empty( $license ) ) {
135 $license = $this->activate_defined_license();
136 }
137
138 return $license;
139 }
140
141 /**
142 * @since 3.04.03
143 */
144 protected function maybe_get_pro_license() {
145 // prevent a loop if $this is the pro plugin
146 $get_license = FrmAppHelper::pro_is_installed() && is_callable( 'FrmProAppHelper::get_updater' ) && $this->plugin_name != 'Formidable Pro';
147
148 if ( ! $get_license ) {
149 return false;
150 }
151
152 $api = new FrmFormApi();
153 $api->get_pro_updater();
154 $license = $api->get_license();
155 if ( empty( $license ) ) {
156 return false;
157 }
158
159 $this->get_api_info( $license );
160 if ( ! $this->is_parent_licence ) {
161 $license = false;
162 }
163
164 return $license;
165 }
166
167 /**
168 * Activate the license in wp-config.php
169 *
170 * @since 2.04
171 */
172 public function activate_defined_license() {
173 $license = $this->get_defined_license();
174 if ( ! empty( $license ) && ! $this->is_active() && $this->is_time_to_auto_activate() ) {
175 $response = $this->activate_license( $license );
176 $this->set_auto_activate_time();
177 if ( ! $response['success'] ) {
178 $license = '';
179 }
180 }
181
182 return $license;
183 }
184
185 /**
186 * Check the wp-config.php for the license key
187 *
188 * @since 2.04
189 */
190 public function get_defined_license() {
191 $consant_name = 'FRM_' . strtoupper( $this->plugin_slug ) . '_LICENSE';
192
193 return defined( $consant_name ) ? constant( $consant_name ) : false;
194 }
195
196 public function set_license( $license ) {
197 update_option( $this->option_name . 'key', $license );
198 }
199
200 /**
201 * If the license is in the config, limit the frequency of checks.
202 * The license may be entered incorrectly, so we don't want to check on every page load.
203 *
204 * @since 2.04
205 */
206 private function is_time_to_auto_activate() {
207 $last_try = get_option( $this->option_name . 'last_activate' );
208
209 return ( ! $last_try || $last_try < strtotime( '-1 day' ) );
210 }
211
212 private function set_auto_activate_time() {
213 update_option( $this->option_name . 'last_activate', time() );
214 }
215
216 public function is_active() {
217 return get_option( $this->option_name . 'active' );
218 }
219
220 /**
221 * @since 3.04.03
222 *
223 * @param array error
224 */
225 public function maybe_clear_license( $error ) {
226 if ( $error['code'] === 'disabled' && $error['license'] === $this->license ) {
227 $this->clear_license();
228 }
229 }
230
231 public function clear_license() {
232 delete_option( $this->option_name . 'active' );
233 delete_option( $this->option_name . 'key' );
234 delete_site_option( $this->transient_key() );
235 delete_option( $this->transient_key() );
236 $this->delete_cache();
237 }
238
239 public function set_active( $is_active ) {
240 update_option( $this->option_name . 'active', $is_active );
241 $this->delete_cache();
242 FrmAppHelper::save_combined_js();
243 $this->update_pro_capabilities();
244 }
245
246 /**
247 * Updates roles capabilities after pro license is active.
248 *
249 * @since 5.0
250 */
251 protected function update_pro_capabilities() {
252 global $wp_roles;
253
254 if ( ! function_exists( 'get_editable_roles' ) ) {
255 require_once ABSPATH . 'wp-admin/includes/user.php';
256 }
257
258 $caps = FrmAppHelper::frm_capabilities( 'pro_only' );
259 $roles = get_editable_roles();
260 $settings = new FrmSettings();
261 foreach ( $caps as $cap => $cap_desc ) {
262 $cap_roles = (array) ( isset( $settings->$cap ) ? $settings->$cap : 'administrator' );
263
264 // Make sure administrators always have permissions.
265 if ( ! in_array( 'administrator', $cap_roles ) ) {
266 array_push( $cap_roles, 'administrator' );
267 }
268
269 foreach ( $roles as $role => $details ) {
270 if ( in_array( $role, $cap_roles ) ) {
271 $wp_roles->add_cap( $role, $cap );
272 } else {
273 $wp_roles->remove_cap( $role, $cap );
274 }
275 }
276 }
277 }
278
279 /**
280 * @since 3.04.03
281 */
282 protected function delete_cache() {
283 delete_transient( 'frm_api_licence' );
284
285 $api = new FrmFormApi( $this->license );
286 $api->reset_cached();
287
288 $api = new FrmFormTemplateApi( $this->license );
289 $api->reset_cached();
290
291 $api = new FrmApplicationApi( $this->license );
292 $api->reset_cached();
293 }
294
295 /**
296 * The Pro version includes the show_license_message function.
297 * We need an extra check before we allow it to show a message.
298 *
299 * @since 3.04.03
300 */
301 public function maybe_show_license_message( $file, $plugin ) {
302 if ( $this->is_expired_addon || isset( $plugin['package'] ) ) {
303 // let's not show a ton of duplicate messages
304 return;
305 }
306
307 $this->show_license_message( $file, $plugin );
308 }
309
310 public function show_license_message( $file, $plugin ) {
311 $message = '';
312 if ( empty( $this->license ) ) {
313 /* translators: %1$s: Plugin name, %2$s: Start link HTML, %3$s: end link HTML */
314 $message = sprintf( esc_html__( 'Your %1$s license key is missing. Please add it on the %2$slicenses page%3$s.', 'formidable' ), esc_html( $this->plugin_name ), '<a href="' . esc_url( admin_url( 'admin.php?page=formidable-settings' ) ) . '">', '</a>' );
315 } else {
316 $api = new FrmFormApi( $this->license );
317 $errors = $api->error_for_license();
318 if ( ! empty( $errors ) ) {
319 $message = reset( $errors );
320 }
321 }
322
323 if ( empty( $message ) ) {
324 return;
325 }
326
327 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
328 $id = sanitize_title( $plugin['Name'] ) . '-next';
329
330 echo '<tr class="plugin-update-tr active" id="' . esc_attr( $id ) . '"><td colspan="' . esc_attr( $wp_list_table->get_column_count() ) . '" class="plugin-update colspanchange"><div class="update-message notice error inline notice-error notice-alt"><p>';
331 echo FrmAppHelper::kses( $message, 'a' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
332 echo '<script type="text/javascript">var d = document.getElementById("' . esc_attr( $id ) . '").previousSibling;if ( d !== null ){ d.className = d.className + " update"; }</script>';
333 echo '</p></div></td></tr>';
334 }
335
336 public function clear_expired_download( $transient ) {
337 if ( ! is_object( $transient ) ) {
338 return $transient;
339 }
340
341 if ( $this->is_current_version( $transient ) ) {
342 //make sure it doesn't show there is an update if plugin is up-to-date
343 if ( isset( $transient->response[ $this->plugin_folder ] ) ) {
344 unset( $transient->response[ $this->plugin_folder ] );
345 }
346 } elseif ( isset( $transient->response ) && isset( $transient->response[ $this->plugin_folder ] ) ) {
347 $this->prepare_update_details( $transient->response[ $this->plugin_folder ] );
348
349 // if the transient has expired, clear the update and trigger it again
350 if ( $transient->response[ $this->plugin_folder ] === false ) {
351 if ( ! $this->has_been_cleared() ) {
352 $this->cleared_plugins();
353 $this->manually_queue_update();
354 }
355 unset( $transient->response[ $this->plugin_folder ] );
356 }
357 }
358
359 return $transient;
360 }
361
362 /**
363 * Check if the plugin information is correct to allow an update
364 *
365 * @since 3.04.03
366 *
367 * @param object $transient - the current plugin info saved for update
368 */
369 private function prepare_update_details( &$transient ) {
370 $version_info = $transient;
371 $has_beta_url = isset( $version_info->beta ) && ! empty( $version_info->beta );
372 if ( $this->get_beta && ! $has_beta_url ) {
373 $version_info = (object) $this->get_api_info( $this->license );
374 }
375
376 if ( isset( $version_info->new_version ) && ! empty( $version_info->new_version ) ) {
377 $this->clear_old_plugin_version( $version_info );
378 if ( $version_info === false ) { // was cleared with timeout
379 $transient = false;
380 } else {
381 $this->maybe_use_beta_url( $version_info );
382
383 if ( version_compare( $version_info->new_version, $this->version, '>' ) ) {
384 $transient = $version_info;
385 }
386 }
387 }
388 }
389
390 /**
391 * Get the API info for this plugin
392 *
393 * @since 3.04.03
394 */
395 protected function get_api_info( $license ) {
396 $api = new FrmFormApi( $license );
397 $addon = $api->get_addon_for_license( $this );
398
399 // if there is no download url, this license does not apply to the addon
400 if ( isset( $addon['package'] ) ) {
401 $this->is_parent_licence = true;
402 } elseif ( isset( $addon['error'] ) ) {
403 // if the license is expired, we must assume all add-ons were packaged
404 $this->is_parent_licence = true;
405 $this->is_expired_addon = true;
406 }
407
408 return $addon;
409 }
410
411 /**
412 * Make sure transients don't stick around on sites that
413 * don't save the transient expiration
414 *
415 * @since 2.05.05
416 */
417 private function clear_old_plugin_version( &$version_info ) {
418 $timeout = ( isset( $version_info->timeout ) && ! empty( $version_info->timeout ) ) ? $version_info->timeout : 0;
419 if ( ! empty( $timeout ) && time() > $timeout ) {
420 $version_info = false; // Cache is expired
421 $api = new FrmFormApi( $this->license );
422 $api->reset_cached();
423 }
424 }
425
426 /**
427 * The beta url is always included if the download has a beta.
428 * Check if the beta should be downloaded.
429 *
430 * @since 3.04.03
431 */
432 private function maybe_use_beta_url( &$version_info ) {
433 if ( $this->get_beta && isset( $version_info->beta ) && ! empty( $version_info->beta ) ) {
434 $version_info->new_version = $version_info->beta['version'];
435 $version_info->package = $version_info->beta['package'];
436 if ( isset( $version_info->plugin ) && ! empty( $version_info->plugin ) ) {
437 $version_info->plugin = $version_info->beta['plugin'];
438 }
439 }
440 }
441
442 private function is_current_version( $transient ) {
443 if ( empty( $transient->checked ) || ! isset( $transient->checked[ $this->plugin_folder ] ) ) {
444 return false;
445 }
446
447 $response = ! isset( $transient->response ) || empty( $transient->response );
448 if ( $response ) {
449 return true;
450 }
451
452 return isset( $transient->response ) && isset( $transient->response[ $this->plugin_folder ] ) && $transient->checked[ $this->plugin_folder ] === $transient->response[ $this->plugin_folder ]->new_version;
453 }
454
455 private function has_been_cleared() {
456 $last_cleared = get_option( 'frm_last_cleared' );
457
458 return ( $last_cleared && $last_cleared > gmdate( 'Y-m-d H:i:s', strtotime( '-5 minutes' ) ) );
459 }
460
461 private function cleared_plugins() {
462 update_option( 'frm_last_cleared', gmdate( 'Y-m-d H:i:s' ) );
463 }
464
465 private function is_license_revoked() {
466 if ( empty( $this->license ) || empty( $this->plugin_slug ) || isset( $_POST['license'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
467 return;
468 }
469
470 if ( is_multisite() ) {
471 $last_checked = get_site_option( $this->transient_key() );
472 } else {
473 $last_checked = get_option( $this->transient_key() );
474 }
475
476 $seven_days_ago = gmdate( 'Y-m-d H:i:s', strtotime( '-7 days' ) );
477
478 if ( ! $last_checked || $last_checked < $seven_days_ago ) {
479 // check weekly
480 if ( is_multisite() ) {
481 update_site_option( $this->transient_key(), gmdate( 'Y-m-d H:i:s' ) );
482 } else {
483 update_option( $this->transient_key(), gmdate( 'Y-m-d H:i:s' ) );
484 }
485
486 $response = $this->get_license_status();
487 if ( 'revoked' === $response['status'] || 'blocked' === $response['status'] || 'disabled' === $response['status'] || 'missing' === $response['status'] ) {
488 $this->clear_license();
489 }
490 }
491 }
492
493 /**
494 * Use a new cache after the license is changed, or Formidable is updated.
495 */
496 private function transient_key() {
497 return 'frm_' . md5( sanitize_key( $this->license . '_' . $this->plugin_slug ) );
498 }
499
500 public static function activate() {
501 FrmAppHelper::permission_check( 'frm_change_settings' );
502 check_ajax_referer( 'frm_ajax', 'nonce' );
503
504 $license = stripslashes( FrmAppHelper::get_param( 'license', '', 'post', 'sanitize_text_field' ) );
505 if ( empty( $license ) ) {
506 wp_die(
507 json_encode(
508 array(
509 'message' => __( 'Oops! You forgot to enter your license number.', 'formidable' ),
510 'success' => false,
511 )
512 )
513 );
514 }
515
516 $plugin_slug = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
517 $response = self::activate_license_for_plugin( $license, $plugin_slug );
518
519 echo json_encode( $response );
520 wp_die();
521 }
522
523 /**
524 * @since 4.08
525 */
526 public static function activate_license_for_plugin( $license, $plugin_slug ) {
527 $this_plugin = self::get_addon( $plugin_slug );
528 return $this_plugin->activate_license( $license );
529 }
530
531 private function activate_license( $license ) {
532 $this->set_license( $license );
533 $this->license = $license;
534
535 $response = $this->get_license_status();
536 $response['message'] = '';
537 $response['success'] = false;
538
539 if ( $response['error'] ) {
540 $response['message'] = $response['status'];
541 } else {
542 $messages = $this->get_messages();
543 if ( is_string( $response['status'] ) && isset( $messages[ $response['status'] ] ) ) {
544 $response['message'] = $messages[ $response['status'] ];
545 } else {
546 $response['message'] = FrmAppHelper::kses( $response['status'], array( 'a' ) );
547 }
548
549 $is_valid = false;
550 if ( 'valid' === $response['status'] ) {
551 $is_valid = 'valid';
552 $response['success'] = true;
553 }
554 $this->set_active( $is_valid );
555 }
556
557 return $response;
558 }
559
560 private function get_license_status() {
561 $response = array(
562 'status' => 'missing',
563 'error' => true,
564 );
565 if ( empty( $this->license ) ) {
566 $response['error'] = false;
567
568 return $response;
569 }
570
571 try {
572 $response['error'] = false;
573 $license_data = $this->send_mothership_request( 'activate_license' );
574
575 // $license_data->license will be either "valid" or "invalid"
576 if ( is_array( $license_data ) ) {
577 if ( in_array( $license_data['license'], array( 'valid', 'invalid' ), true ) ) {
578 $response['status'] = $license_data['license'];
579 }
580 } else {
581 $response['status'] = $license_data;
582 }
583 } catch ( Exception $e ) {
584 $response['status'] = $e->getMessage();
585 }
586
587 return $response;
588 }
589
590 private function get_messages() {
591 return array(
592 'valid' => __( 'Your license has been activated. Enjoy!', 'formidable' ),
593 'invalid' => __( 'That license key is invalid', 'formidable' ),
594 'expired' => __( 'That license is expired', 'formidable' ),
595 'revoked' => __( 'That license has been refunded', 'formidable' ),
596 'no_activations_left' => __( 'That license has been used on too many sites', 'formidable' ),
597 'invalid_item_id' => __( 'Oops! That is the wrong license key for this plugin.', 'formidable' ),
598 'missing' => __( 'That license key is invalid', 'formidable' ),
599 );
600 }
601
602 /**
603 * @since 4.03
604 */
605 public static function reset_cache() {
606 FrmAppHelper::permission_check( 'frm_change_settings' );
607 check_ajax_referer( 'frm_ajax', 'nonce' );
608
609 $this_plugin = self::set_license_from_post();
610 $this_plugin->delete_cache();
611
612 $response = array(
613 'success' => true,
614 'message' => __( 'Cache cleared', 'formidable' ),
615 );
616
617 echo json_encode( $response );
618 wp_die();
619 }
620
621 public static function deactivate() {
622 FrmAppHelper::permission_check( 'frm_change_settings' );
623 check_ajax_referer( 'frm_ajax', 'nonce' );
624
625 $this_plugin = self::set_license_from_post();
626
627 $response = array(
628 'success' => false,
629 'message' => '',
630 );
631 try {
632 // $license_data->license will be either "deactivated" or "failed"
633 $license_data = $this_plugin->send_mothership_request( 'deactivate_license' );
634 if ( is_array( $license_data ) && 'deactivated' === $license_data['license'] ) {
635 $response['success'] = true;
636 $response['message'] = __( 'That license was removed successfully', 'formidable' );
637 } else {
638 $response['message'] = __( 'There was an error deactivating your license.', 'formidable' );
639 }
640 } catch ( Exception $e ) {
641 $response['message'] = $e->getMessage();
642 }
643
644 $this_plugin->clear_license();
645
646 echo json_encode( $response );
647 wp_die();
648 }
649
650 /**
651 * @since 4.03
652 */
653 private static function set_license_from_post() {
654 $plugin_slug = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
655 $this_plugin = self::get_addon( $plugin_slug );
656 $license = $this_plugin->get_license();
657 $this_plugin->license = $license;
658 return $this_plugin;
659 }
660
661 public function send_mothership_request( $action ) {
662 $api_params = array(
663 'edd_action' => $action,
664 'license' => $this->license,
665 'url' => home_url(),
666 );
667 if ( is_numeric( $this->download_id ) ) {
668 $api_params['item_id'] = absint( $this->download_id );
669 } else {
670 $api_params['item_name'] = rawurlencode( $this->plugin_name );
671 }
672
673 $arg_array = array(
674 'body' => $api_params,
675 'timeout' => 25,
676 'user-agent' => $this->plugin_slug . '/' . $this->version . '; ' . get_bloginfo( 'url' ),
677 );
678
679 $resp = wp_remote_post( $this->store_url, $arg_array );
680 $body = wp_remote_retrieve_body( $resp );
681
682 $message = __( 'Your License Key was invalid', 'formidable' );
683 if ( is_wp_error( $resp ) ) {
684 $link = FrmAppHelper::admin_upgrade_link( 'api', 'knowledgebase/why-cant-i-activate-formidable-pro/' );
685 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
686 $message = sprintf( __( 'You had an error communicating with the Formidable API. %1$sClick here%2$s for more information.', 'formidable' ), '<a href="' . esc_url( $link ) . '" target="_blank">', '</a>' );
687 $message .= ' ' . $resp->get_error_message();
688 } elseif ( 'error' === $body || is_wp_error( $body ) ) {
689 $message = __( 'You had an HTTP error connecting to the Formidable API', 'formidable' );
690 } else {
691 $json_res = json_decode( $body, true );
692 if ( null !== $json_res ) {
693 if ( is_array( $json_res ) && isset( $json_res['error'] ) ) {
694 $message = $json_res['error'];
695 } else {
696 $message = $json_res;
697 }
698 } elseif ( isset( $resp['response'] ) && isset( $resp['response']['code'] ) ) {
699 /* translators: %1$s: Error code, %2$s: Error message */
700 $message = sprintf( __( 'There was a %1$s error: %2$s', 'formidable' ), $resp['response']['code'], $resp['response']['message'] . ' ' . $resp['body'] );
701 }
702 }
703
704 return $message;
705 }
706
707 public function manually_queue_update() {
708 $updates = new stdClass();
709 $updates->last_checked = 0;
710 $updates->response = array();
711 $updates->translations = array();
712 $updates->no_update = array();
713 $updates->checked = array();
714 set_site_transient( 'update_plugins', $updates );
715 }
716 }
717