PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 5.4.4
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v5.4.4
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.4.4, at classes/models/FrmAddon.php

713 lines 21.2 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 $caps = FrmAppHelper::frm_capabilities( 'pro_only' );
255 $roles = get_editable_roles();
256 $settings = new FrmSettings();
257 foreach ( $caps as $cap => $cap_desc ) {
258 $cap_roles = (array) ( isset( $settings->$cap ) ? $settings->$cap : 'administrator' );
259
260 // Make sure administrators always have permissions.
261 if ( ! in_array( 'administrator', $cap_roles ) ) {
262 array_push( $cap_roles, 'administrator' );
263 }
264
265 foreach ( $roles as $role => $details ) {
266 if ( in_array( $role, $cap_roles ) ) {
267 $wp_roles->add_cap( $role, $cap );
268 } else {
269 $wp_roles->remove_cap( $role, $cap );
270 }
271 }
272 }
273 }
274
275 /**
276 * @since 3.04.03
277 */
278 protected function delete_cache() {
279 delete_transient( 'frm_api_licence' );
280
281 $api = new FrmFormApi( $this->license );
282 $api->reset_cached();
283
284 $api = new FrmFormTemplateApi( $this->license );
285 $api->reset_cached();
286
287 $api = new FrmApplicationApi( $this->license );
288 $api->reset_cached();
289 }
290
291 /**
292 * The Pro version includes the show_license_message function.
293 * We need an extra check before we allow it to show a message.
294 *
295 * @since 3.04.03
296 */
297 public function maybe_show_license_message( $file, $plugin ) {
298 if ( $this->is_expired_addon || isset( $plugin['package'] ) ) {
299 // let's not show a ton of duplicate messages
300 return;
301 }
302
303 $this->show_license_message( $file, $plugin );
304 }
305
306 public function show_license_message( $file, $plugin ) {
307 $message = '';
308 if ( empty( $this->license ) ) {
309 /* translators: %1$s: Plugin name, %2$s: Start link HTML, %3$s: end link HTML */
310 $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>' );
311 } else {
312 $api = new FrmFormApi( $this->license );
313 $errors = $api->error_for_license();
314 if ( ! empty( $errors ) ) {
315 $message = reset( $errors );
316 }
317 }
318
319 if ( empty( $message ) ) {
320 return;
321 }
322
323 $wp_list_table = _get_list_table( 'WP_Plugins_List_Table' );
324 $id = sanitize_title( $plugin['Name'] ) . '-next';
325
326 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>';
327 echo FrmAppHelper::kses( $message, 'a' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
328 echo '<script type="text/javascript">var d = document.getElementById("' . esc_attr( $id ) . '").previousSibling;if ( d !== null ){ d.className = d.className + " update"; }</script>';
329 echo '</p></div></td></tr>';
330 }
331
332 public function clear_expired_download( $transient ) {
333 if ( ! is_object( $transient ) ) {
334 return $transient;
335 }
336
337 if ( $this->is_current_version( $transient ) ) {
338 //make sure it doesn't show there is an update if plugin is up-to-date
339 if ( isset( $transient->response[ $this->plugin_folder ] ) ) {
340 unset( $transient->response[ $this->plugin_folder ] );
341 }
342 } elseif ( isset( $transient->response ) && isset( $transient->response[ $this->plugin_folder ] ) ) {
343 $this->prepare_update_details( $transient->response[ $this->plugin_folder ] );
344
345 // if the transient has expired, clear the update and trigger it again
346 if ( $transient->response[ $this->plugin_folder ] === false ) {
347 if ( ! $this->has_been_cleared() ) {
348 $this->cleared_plugins();
349 $this->manually_queue_update();
350 }
351 unset( $transient->response[ $this->plugin_folder ] );
352 }
353 }
354
355 return $transient;
356 }
357
358 /**
359 * Check if the plugin information is correct to allow an update
360 *
361 * @since 3.04.03
362 *
363 * @param object $transient - the current plugin info saved for update
364 */
365 private function prepare_update_details( &$transient ) {
366 $version_info = $transient;
367 $has_beta_url = isset( $version_info->beta ) && ! empty( $version_info->beta );
368 if ( $this->get_beta && ! $has_beta_url ) {
369 $version_info = (object) $this->get_api_info( $this->license );
370 }
371
372 if ( isset( $version_info->new_version ) && ! empty( $version_info->new_version ) ) {
373 $this->clear_old_plugin_version( $version_info );
374 if ( $version_info === false ) { // was cleared with timeout
375 $transient = false;
376 } else {
377 $this->maybe_use_beta_url( $version_info );
378
379 if ( version_compare( $version_info->new_version, $this->version, '>' ) ) {
380 $transient = $version_info;
381 }
382 }
383 }
384 }
385
386 /**
387 * Get the API info for this plugin
388 *
389 * @since 3.04.03
390 */
391 protected function get_api_info( $license ) {
392 $api = new FrmFormApi( $license );
393 $addon = $api->get_addon_for_license( $this );
394
395 // if there is no download url, this license does not apply to the addon
396 if ( isset( $addon['package'] ) ) {
397 $this->is_parent_licence = true;
398 } elseif ( isset( $addon['error'] ) ) {
399 // if the license is expired, we must assume all add-ons were packaged
400 $this->is_parent_licence = true;
401 $this->is_expired_addon = true;
402 }
403
404 return $addon;
405 }
406
407 /**
408 * Make sure transients don't stick around on sites that
409 * don't save the transient expiration
410 *
411 * @since 2.05.05
412 */
413 private function clear_old_plugin_version( &$version_info ) {
414 $timeout = ( isset( $version_info->timeout ) && ! empty( $version_info->timeout ) ) ? $version_info->timeout : 0;
415 if ( ! empty( $timeout ) && time() > $timeout ) {
416 $version_info = false; // Cache is expired
417 $api = new FrmFormApi( $this->license );
418 $api->reset_cached();
419 }
420 }
421
422 /**
423 * The beta url is always included if the download has a beta.
424 * Check if the beta should be downloaded.
425 *
426 * @since 3.04.03
427 */
428 private function maybe_use_beta_url( &$version_info ) {
429 if ( $this->get_beta && isset( $version_info->beta ) && ! empty( $version_info->beta ) ) {
430 $version_info->new_version = $version_info->beta['version'];
431 $version_info->package = $version_info->beta['package'];
432 if ( isset( $version_info->plugin ) && ! empty( $version_info->plugin ) ) {
433 $version_info->plugin = $version_info->beta['plugin'];
434 }
435 }
436 }
437
438 private function is_current_version( $transient ) {
439 if ( empty( $transient->checked ) || ! isset( $transient->checked[ $this->plugin_folder ] ) ) {
440 return false;
441 }
442
443 $response = ! isset( $transient->response ) || empty( $transient->response );
444 if ( $response ) {
445 return true;
446 }
447
448 return isset( $transient->response ) && isset( $transient->response[ $this->plugin_folder ] ) && $transient->checked[ $this->plugin_folder ] === $transient->response[ $this->plugin_folder ]->new_version;
449 }
450
451 private function has_been_cleared() {
452 $last_cleared = get_option( 'frm_last_cleared' );
453
454 return ( $last_cleared && $last_cleared > gmdate( 'Y-m-d H:i:s', strtotime( '-5 minutes' ) ) );
455 }
456
457 private function cleared_plugins() {
458 update_option( 'frm_last_cleared', gmdate( 'Y-m-d H:i:s' ) );
459 }
460
461 private function is_license_revoked() {
462 if ( empty( $this->license ) || empty( $this->plugin_slug ) || isset( $_POST['license'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
463 return;
464 }
465
466 if ( is_multisite() ) {
467 $last_checked = get_site_option( $this->transient_key() );
468 } else {
469 $last_checked = get_option( $this->transient_key() );
470 }
471
472 $seven_days_ago = gmdate( 'Y-m-d H:i:s', strtotime( '-7 days' ) );
473
474 if ( ! $last_checked || $last_checked < $seven_days_ago ) {
475 // check weekly
476 if ( is_multisite() ) {
477 update_site_option( $this->transient_key(), gmdate( 'Y-m-d H:i:s' ) );
478 } else {
479 update_option( $this->transient_key(), gmdate( 'Y-m-d H:i:s' ) );
480 }
481
482 $response = $this->get_license_status();
483 if ( 'revoked' === $response['status'] || 'blocked' === $response['status'] || 'disabled' === $response['status'] || 'missing' === $response['status'] ) {
484 $this->clear_license();
485 }
486 }
487 }
488
489 /**
490 * Use a new cache after the license is changed, or Formidable is updated.
491 */
492 private function transient_key() {
493 return 'frm_' . md5( sanitize_key( $this->license . '_' . $this->plugin_slug ) );
494 }
495
496 public static function activate() {
497 FrmAppHelper::permission_check( 'frm_change_settings' );
498 check_ajax_referer( 'frm_ajax', 'nonce' );
499
500 $license = stripslashes( FrmAppHelper::get_param( 'license', '', 'post', 'sanitize_text_field' ) );
501 if ( empty( $license ) ) {
502 wp_die(
503 json_encode(
504 array(
505 'message' => __( 'Oops! You forgot to enter your license number.', 'formidable' ),
506 'success' => false,
507 )
508 )
509 );
510 }
511
512 $plugin_slug = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
513 $response = self::activate_license_for_plugin( $license, $plugin_slug );
514
515 echo json_encode( $response );
516 wp_die();
517 }
518
519 /**
520 * @since 4.08
521 */
522 public static function activate_license_for_plugin( $license, $plugin_slug ) {
523 $this_plugin = self::get_addon( $plugin_slug );
524 return $this_plugin->activate_license( $license );
525 }
526
527 private function activate_license( $license ) {
528 $this->set_license( $license );
529 $this->license = $license;
530
531 $response = $this->get_license_status();
532 $response['message'] = '';
533 $response['success'] = false;
534
535 if ( $response['error'] ) {
536 $response['message'] = $response['status'];
537 } else {
538 $messages = $this->get_messages();
539 if ( is_string( $response['status'] ) && isset( $messages[ $response['status'] ] ) ) {
540 $response['message'] = $messages[ $response['status'] ];
541 } else {
542 $response['message'] = FrmAppHelper::kses( $response['status'], array( 'a' ) );
543 }
544
545 $is_valid = false;
546 if ( 'valid' === $response['status'] ) {
547 $is_valid = 'valid';
548 $response['success'] = true;
549 }
550 $this->set_active( $is_valid );
551 }
552
553 return $response;
554 }
555
556 private function get_license_status() {
557 $response = array(
558 'status' => 'missing',
559 'error' => true,
560 );
561 if ( empty( $this->license ) ) {
562 $response['error'] = false;
563
564 return $response;
565 }
566
567 try {
568 $response['error'] = false;
569 $license_data = $this->send_mothership_request( 'activate_license' );
570
571 // $license_data->license will be either "valid" or "invalid"
572 if ( is_array( $license_data ) ) {
573 if ( in_array( $license_data['license'], array( 'valid', 'invalid' ), true ) ) {
574 $response['status'] = $license_data['license'];
575 }
576 } else {
577 $response['status'] = $license_data;
578 }
579 } catch ( Exception $e ) {
580 $response['status'] = $e->getMessage();
581 }
582
583 return $response;
584 }
585
586 private function get_messages() {
587 return array(
588 'valid' => __( 'Your license has been activated. Enjoy!', 'formidable' ),
589 'invalid' => __( 'That license key is invalid', 'formidable' ),
590 'expired' => __( 'That license is expired', 'formidable' ),
591 'revoked' => __( 'That license has been refunded', 'formidable' ),
592 'no_activations_left' => __( 'That license has been used on too many sites', 'formidable' ),
593 'invalid_item_id' => __( 'Oops! That is the wrong license key for this plugin.', 'formidable' ),
594 'missing' => __( 'That license key is invalid', 'formidable' ),
595 );
596 }
597
598 /**
599 * @since 4.03
600 */
601 public static function reset_cache() {
602 FrmAppHelper::permission_check( 'frm_change_settings' );
603 check_ajax_referer( 'frm_ajax', 'nonce' );
604
605 $this_plugin = self::set_license_from_post();
606 $this_plugin->delete_cache();
607
608 $response = array(
609 'success' => true,
610 'message' => __( 'Cache cleared', 'formidable' ),
611 );
612
613 echo json_encode( $response );
614 wp_die();
615 }
616
617 public static function deactivate() {
618 FrmAppHelper::permission_check( 'frm_change_settings' );
619 check_ajax_referer( 'frm_ajax', 'nonce' );
620
621 $this_plugin = self::set_license_from_post();
622
623 $response = array(
624 'success' => false,
625 'message' => '',
626 );
627 try {
628 // $license_data->license will be either "deactivated" or "failed"
629 $license_data = $this_plugin->send_mothership_request( 'deactivate_license' );
630 if ( is_array( $license_data ) && 'deactivated' === $license_data['license'] ) {
631 $response['success'] = true;
632 $response['message'] = __( 'That license was removed successfully', 'formidable' );
633 } else {
634 $response['message'] = __( 'There was an error deactivating your license.', 'formidable' );
635 }
636 } catch ( Exception $e ) {
637 $response['message'] = $e->getMessage();
638 }
639
640 $this_plugin->clear_license();
641
642 echo json_encode( $response );
643 wp_die();
644 }
645
646 /**
647 * @since 4.03
648 */
649 private static function set_license_from_post() {
650 $plugin_slug = FrmAppHelper::get_param( 'plugin', '', 'post', 'sanitize_text_field' );
651 $this_plugin = self::get_addon( $plugin_slug );
652 $license = $this_plugin->get_license();
653 $this_plugin->license = $license;
654 return $this_plugin;
655 }
656
657 public function send_mothership_request( $action ) {
658 $api_params = array(
659 'edd_action' => $action,
660 'license' => $this->license,
661 'url' => home_url(),
662 );
663 if ( is_numeric( $this->download_id ) ) {
664 $api_params['item_id'] = absint( $this->download_id );
665 } else {
666 $api_params['item_name'] = rawurlencode( $this->plugin_name );
667 }
668
669 $arg_array = array(
670 'body' => $api_params,
671 'timeout' => 25,
672 'user-agent' => $this->plugin_slug . '/' . $this->version . '; ' . get_bloginfo( 'url' ),
673 );
674
675 $resp = wp_remote_post( $this->store_url, $arg_array );
676 $body = wp_remote_retrieve_body( $resp );
677
678 $message = __( 'Your License Key was invalid', 'formidable' );
679 if ( is_wp_error( $resp ) ) {
680 $link = FrmAppHelper::admin_upgrade_link( 'api', 'knowledgebase/why-cant-i-activate-formidable-pro/' );
681 /* translators: %1$s: Start link HTML, %2$s: End link HTML */
682 $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>' );
683 $message .= ' ' . $resp->get_error_message();
684 } elseif ( 'error' === $body || is_wp_error( $body ) ) {
685 $message = __( 'You had an HTTP error connecting to the Formidable API', 'formidable' );
686 } else {
687 $json_res = json_decode( $body, true );
688 if ( null !== $json_res ) {
689 if ( is_array( $json_res ) && isset( $json_res['error'] ) ) {
690 $message = $json_res['error'];
691 } else {
692 $message = $json_res;
693 }
694 } elseif ( isset( $resp['response'] ) && isset( $resp['response']['code'] ) ) {
695 /* translators: %1$s: Error code, %2$s: Error message */
696 $message = sprintf( __( 'There was a %1$s error: %2$s', 'formidable' ), $resp['response']['code'], $resp['response']['message'] . ' ' . $resp['body'] );
697 }
698 }
699
700 return $message;
701 }
702
703 public function manually_queue_update() {
704 $updates = new stdClass();
705 $updates->last_checked = 0;
706 $updates->response = array();
707 $updates->translations = array();
708 $updates->no_update = array();
709 $updates->checked = array();
710 set_site_transient( 'update_plugins', $updates );
711 }
712 }
713