PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.5.5
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.5.5
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Utils / Insights.php

Insights.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.5.5, at includes/Utils/Insights.php

1,133 lines 44.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WPDeveloper\BetterDocs\Utils;
3
4 use AllowDynamicProperties;
5
6 /**
7 * Exit if accessed directly
8 */
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 #[AllowDynamicProperties]
14
15 class Insights {
16 /**
17 * WP Insights Version
18 */
19 const WPINS_VERSION = '3.0.1';
20 /**
21 * API URL
22 */
23 const API_URL = 'https://send.wpinsight.com/process-plugin-data';
24 /**
25 * Installed Plugin File
26 *
27 * @var string
28 */
29 private $plugin_file = null;
30 /**
31 * Installed Plugin Name
32 *
33 * @var string
34 */
35 private $plugin_name = null;
36 /**
37 * How often the event should subsequently
38 *
39 * @var string
40 */
41 public $recurrence = 'daily';
42 private $event_hook = null;
43 private $has_notice = false;
44 private $disabled_wp_cron = false;
45 private $enable_self_cron = false;
46 private $require_optin = false;
47 private $include_goodbye_form = false;
48 private $marketing = false;
49 private $options = [];
50 private $notice_options = [];
51 private $item_id = false;
52 /**
53 * Instace of BetterDocs_Plugin_Usage_Tracker
54 *
55 * @var BetterDocs_Plugin_Usage_Tracker
56 */
57 private static $_instance = null;
58 /**
59 * Get Instance of BetterDocs_Plugin_Usage_Tracker
60 *
61 * @return BetterDocs_Plugin_Usage_Tracker
62 */
63 public static function get_instance( $plugin_file, $args = [] ) {
64 if ( is_null( static::$_instance ) ) {
65 static::$_instance = new static( $plugin_file, $args );
66 }
67 return static::$_instance;
68 }
69 /**
70 * Automatically Invoked when initialized.
71 *
72 * @param array $args
73 */
74 public function __construct( $plugin_file, $args = [] ) {
75 $this->plugin_file = $plugin_file;
76 $this->plugin_name = basename( $this->plugin_file, '.php' );
77 $this->disabled_wp_cron = defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON == true;
78 $this->enable_self_cron = $this->disabled_wp_cron == true ? true : false;
79
80 $this->event_hook = 'put_do_weekly_action';
81
82 $this->require_optin = isset( $args['opt_in'] ) ? $args['opt_in'] : true;
83 $this->include_goodbye_form = isset( $args['goodbye_form'] ) ? $args['goodbye_form'] : true;
84 $this->marketing = isset( $args['email_marketing'] ) ? $args['email_marketing'] : true;
85 $this->options = isset( $args['options'] ) ? $args['options'] : [];
86 $this->item_id = isset( $args['item_id'] ) ? $args['item_id'] : false;
87 /**
88 * Activation Hook
89 */
90 register_activation_hook( $this->plugin_file, array( $this, 'activate_this_plugin' ) );
91 /**
92 * Deactivation Hook
93 */
94 register_deactivation_hook( $this->plugin_file, array( $this, 'deactivate_this_plugin' ) );
95 }
96 /**
97 * When user agreed to opt-in tracking schedule is enabled.
98 *
99 * @since 2.5.0
100 */
101 public function schedule_tracking() {
102 if ( $this->disabled_wp_cron ) {
103 return;
104 }
105 if ( ! wp_next_scheduled( $this->event_hook ) ) {
106 wp_schedule_event( time(), $this->recurrence, $this->event_hook );
107 }
108 }
109 /**
110 * Add the schedule event if the plugin is tracked.
111 *
112 * @return void
113 */
114 public function activate_this_plugin() {
115 $allow_tracking = $this->is_tracking_allowed();
116 if ( ! $allow_tracking ) {
117 return;
118 }
119 $this->schedule_tracking();
120 }
121 /**
122 * Remove the schedule event when plugin is deactivated and send the deactivated reason to inishghts if user submitted.
123 *
124 * @since 2.5.0
125 */
126 public function deactivate_this_plugin() {
127 /**
128 * Check tracking is allowed or not.
129 */
130 $allow_tracking = $this->is_tracking_allowed();
131 if ( ! $allow_tracking ) {
132 return;
133 }
134 $body = $this->get_data();
135 $body['status'] = 'Deactivated';
136 $body['deactivated_date'] = time();
137
138 // Check deactivation reason and add for insights data.
139 if ( false !== get_option( 'wpins_deactivation_reason_' . $this->plugin_name ) ) {
140 $body['deactivation_reason'] = get_option( 'wpins_deactivation_reason_' . $this->plugin_name );
141 }
142 if ( false !== get_option( 'wpins_deactivation_details_' . $this->plugin_name ) ) {
143 $body['deactivation_details'] = get_option( 'wpins_deactivation_details_' . $this->plugin_name );
144 }
145
146 $this->send_data( $body );
147 delete_option( 'wpins_deactivation_reason_' . $this->plugin_name );
148 delete_option( 'wpins_deactivation_details_' . $this->plugin_name );
149 /**
150 * Clear the event schedule.
151 */
152 if ( ! $this->disabled_wp_cron ) {
153 wp_clear_scheduled_hook( $this->event_hook );
154 }
155 }
156 /**
157 * Initial Method to Hook Everything.
158 *
159 * @return void
160 */
161 public function init() {
162 add_action( 'wpdeveloper_notice_clicked_for_' . $this->plugin_name, array( $this, 'clicked' ) );
163 add_action( $this->event_hook, array( $this, 'do_tracking' ) );
164 // For Test
165 add_action( 'wpdeveloper_optin_notice_for_' . $this->plugin_name, array( $this, 'notice' ) );
166 /**
167 * Deactivation Reason Form and Submit Data to Insights.
168 */
169 if ( ! is_plugin_active( 'betterdocs-pro/betterdocs-pro.php' ) ) {
170 add_filter( 'plugin_action_links_' . plugin_basename( $this->plugin_file ), array( $this, 'deactivate_action_links' ) );
171 add_action( 'admin_print_footer_scripts', array( $this, 'notice_script' ) );
172 add_action( 'admin_footer-plugins.php', array( $this, 'deactivate_reasons_form' ) );
173 add_action( 'wp_ajax_deactivation_form_' . esc_attr( $this->plugin_name ), array( $this, 'deactivate_reasons_form_submit' ) );
174 }
175 }
176 /**
177 * For Redirecting Current Page without Arguments!
178 *
179 * @return string
180 */
181 private function redirect_to() {
182 $request_payload = isset( $_SERVER['REQUEST_URI'] ) ? esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) : '';
183 $request_uri = wp_parse_url( $request_payload, PHP_URL_PATH );
184 $query_string = wp_parse_url( $request_payload, PHP_URL_QUERY );
185 parse_str( $query_string, $current_url );
186
187 $unset_array = array( 'dismiss', 'plugin', '_wpnonce', 'later', 'plugin_action', 'marketing_optin' );
188
189 foreach ( $unset_array as $value ) {
190 if ( isset( $current_url[ $value ] ) ) {
191 unset( $current_url[ $value ] );
192 }
193 }
194
195 $current_url = http_build_query( $current_url );
196 $redirect_url = $request_uri . '?' . $current_url;
197 return $redirect_url;
198 }
199 /**
200 * This method forcing the do_tracking method to execute instant.
201 *
202 * @return void
203 */
204 public function force_tracking() {
205 $this->do_tracking( true );
206 }
207 /**
208 * This method is responsible for all the magic from the front of the plugin.
209 *
210 * @since 2.5.0
211 * @param $force Force tracking if it's not the correct time to track/
212 */
213 public function do_tracking( $force = false ) {
214 /**
215 * Check URL is set or not.
216 */
217 if ( empty( self::API_URL ) ) {
218 return;
219 }
220 /**
221 * Check is tracking allowed or not.
222 */
223 if ( ! $this->is_tracking_allowed() ) {
224 return;
225 }
226 /**
227 * Check is this the correct time to track or not.
228 * or Force to track.
229 */
230 if ( ! $this->is_time_to_track() && ! $force ) {
231 return;
232 }
233 /**
234 * Get All Data.
235 */
236 $body = $this->get_data();
237 /**
238 * Send all data.
239 */
240 return $this->send_data( $body );
241 }
242 /**
243 * Is tracking allowed?
244 *
245 * @since 1.0.0
246 */
247 private function is_tracking_allowed() {
248 // First, check if the user has changed their mind and opted out of tracking
249 if ( $this->has_user_opted_out() ) {
250 $this->set_is_tracking_allowed( false, $this->plugin_name );
251 return false;
252 }
253 // The wpins_allow_tracking option is an array of plugins that are being tracked
254 $allow_tracking = get_option( 'wpins_allow_tracking' );
255 // If this plugin is in the array, then tracking is allowed
256 if ( isset( $allow_tracking[ $this->plugin_name ] ) ) {
257 return true;
258 }
259 return false;
260 }
261 /**
262 * Set a flag in DB If tracking is allowed.
263 *
264 * @since 2.5.0
265 * @param $is_allowed Boolean true if is allowed.
266 */
267 public function set_is_tracking_allowed( $is_allowed, $plugin = null ) {
268 if ( empty( $plugin ) ) {
269 $plugin = $this->plugin_name;
270 }
271 /**
272 * Get All Tracked Plugin List using this Tracker.
273 */
274 $allow_tracking = get_option( 'wpins_allow_tracking' );
275 /**
276 * Check user is opted out for tracking or not.
277 */
278 if ( $this->has_user_opted_out() ) {
279 if ( isset( $allow_tracking[ $plugin ] ) ) {
280 unset( $allow_tracking[ $plugin ] );
281 }
282 } elseif ( $is_allowed || ! $this->require_optin ) {
283 /**
284 * If user has agreed to allow tracking
285 */
286 if ( empty( $allow_tracking ) || ! is_array( $allow_tracking ) ) {
287 $allow_tracking = array( $plugin => $plugin );
288 } else {
289 $allow_tracking[ $plugin ] = $plugin;
290 }
291 } elseif ( isset( $allow_tracking[ $plugin ] ) ) {
292 unset( $allow_tracking[ $plugin ] );
293 }
294 update_option( 'wpins_allow_tracking', $allow_tracking, 'no' );
295 }
296
297 /**
298 * Check the user has opted out or not.
299 *
300 * @since 2.5.0
301 * @return boolean
302 */
303 protected function has_user_opted_out() {
304 if ( ! empty( $this->options ) ) {
305 foreach ( $this->options as $option_name ) {
306 $options = get_option( $option_name );
307 if ( ! empty( $options['wpins_opt_out'] ) ) {
308 return true;
309 }
310 }
311 }
312 return false;
313 }
314 /**
315 * Check if it's time to track
316 *
317 * @since 2.5.0
318 */
319 public function is_time_to_track() {
320 $track_times = get_option( 'wpins_last_track_time', array() );
321 return ! isset( $track_times[ $this->plugin_name ] ) ? true :
322 ( ( isset( $track_times[ $this->plugin_name ] ) && $track_times[ $this->plugin_name ] ) < strtotime( '-1 day' ) ? true : false );
323 }
324 /**
325 * Set tracking time.
326 *
327 * @since 2.5.0
328 */
329 public function set_track_time() {
330 $track_times = get_option( 'wpins_last_track_time', array() );
331 $track_times[ $this->plugin_name ] = time();
332 update_option( 'wpins_last_track_time', $track_times, 'no' );
333 }
334 /**
335 * This method is responsible for collecting all data.
336 *
337 * @since 2.5.0
338 */
339 public function get_data() {
340 $body = array(
341 'plugin_slug' => sanitize_text_field( $this->plugin_name ),
342 'url' => get_bloginfo( 'url' ),
343 'site_name' => get_bloginfo( 'name' ),
344 'site_version' => get_bloginfo( 'version' ),
345 'site_language' => get_bloginfo( 'language' ),
346 'charset' => get_bloginfo( 'charset' ),
347 'wpins_version' => self::WPINS_VERSION,
348 'php_version' => phpversion(),
349 'multisite' => is_multisite(),
350 'file_location' => __FILE__,
351 );
352
353 // Collect the email if the correct option has been set
354 if ( $this->marketing ) {
355 if ( ! function_exists( 'wp_get_current_user' ) ) {
356 include ABSPATH . 'wp-includes/pluggable.php';
357 }
358 $current_user = wp_get_current_user();
359 $email = $current_user->user_email;
360 if ( is_email( $email ) ) {
361 $body['email'] = $email;
362 }
363 }
364 $body['marketing_method'] = $this->marketing;
365 $body['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : ''; //phpcs:ignore
366
367 /**
368 * Collect all active and inactive plugins
369 */
370 if ( ! function_exists( 'get_plugins' ) ) {
371 include ABSPATH . '/wp-admin/includes/plugin.php';
372 }
373 $plugins = array_keys( get_plugins() );
374 $active_plugins = is_network_admin() ? array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) : get_option( 'active_plugins', array() );
375 foreach ( $plugins as $key => $plugin ) {
376 if ( in_array( $plugin, $active_plugins ) ) {
377 unset( $plugins[ $key ] );
378 }
379 }
380 $body['active_plugins'] = $active_plugins;
381 $body['inactive_plugins'] = $plugins;
382
383 /**
384 * Text Direction.
385 */
386 $body['text_direction'] = ( function_exists( 'is_rtl' ) ? ( is_rtl() ? 'RTL' : 'LTR' ) : 'NOT SET' );
387 /**
388 * Get Our Plugin Data.
389 *
390 * @since 2.5.0
391 */
392 $plugin = $this->plugin_data();
393 if ( empty( $plugin ) ) {
394 $body['message'] .= __( 'We can\'t detect any plugin information. This is most probably because you have not included the code in the plugin main file.', 'betterdocs' );
395 $body['status'] = 'NOT FOUND';
396 } else {
397 if ( isset( $plugin['Name'] ) ) {
398 $body['plugin'] = sanitize_text_field( $plugin['Name'] );
399 }
400 if ( isset( $plugin['Version'] ) ) {
401 $body['version'] = sanitize_text_field( $plugin['Version'] );
402 }
403 $body['status'] = 'Active';
404 }
405
406 /**
407 * Get active theme name and version
408 *
409 * @since 2.5.0
410 */
411 $theme = wp_get_theme();
412 if ( $theme->Name ) {
413 $body['theme'] = sanitize_text_field( $theme->Name );
414 }
415 if ( $theme->Version ) {
416 $body['theme_version'] = sanitize_text_field( $theme->Version );
417 }
418 return $body;
419 }
420
421 /**
422 * Collect plugin data,
423 * Retrieve current plugin information
424 *
425 * @since 2.5.0
426 */
427 public function plugin_data() {
428 if ( ! function_exists( 'get_plugin_data' ) ) {
429 include ABSPATH . '/wp-admin/includes/plugin.php';
430 }
431 $plugin = get_plugin_data( $this->plugin_file );
432 return $plugin;
433 }
434 /**
435 * Send the data to insights.
436 *
437 * @since 2.5.0
438 */
439 public function send_data( $body ) {
440 /**
441 * Get SITE ID
442 */
443 $site_id_key = "wpins_{$this->plugin_name}_site_id";
444 $site_id = get_option( $site_id_key, false );
445 $failed_data = [];
446 $site_url = get_bloginfo( 'url' );
447 $original_site_url = get_option( "wpins_{$this->plugin_name}_original_url", false );
448 if ( $original_site_url === false && version_compare( $body['wpins_version'], '3.0.1', '==' ) ) {
449 $site_id = false;
450 }
451 /**
452 * Send Initial Data to API
453 */
454 if ( $site_id == false && $this->item_id !== false && $original_site_url === false ) {
455 if ( isset( $_SERVER['REMOTE_ADDR'] ) && ! empty( $_SERVER['REMOTE_ADDR'] && $_SERVER['REMOTE_ADDR'] != '127.0.0.1' ) ) { //phpcs:ignore
456 $country_request = wp_remote_get( 'http://ip-api.com/json/' . $_SERVER['REMOTE_ADDR'] . '?fields=country' ); //phpcs:ignore
457 if ( ! is_wp_error( $country_request ) && $country_request['response']['code'] == 200 ) {
458 $ip_data = json_decode( $country_request['body'] );
459 $body['country'] = isset( $ip_data->country ) ? $ip_data->country : 'NOT SET';
460 }
461 }
462
463 $body['plugin_slug'] = $this->plugin_name;
464 $body['url'] = $site_url;
465 $body['item_id'] = $this->item_id;
466
467 $request = $this->remote_post( $body );
468 if ( ! is_wp_error( $request ) && $request['response']['code'] == 200 ) {
469 $retrieved_body = json_decode( wp_remote_retrieve_body( $request ), true );
470 if ( is_array( $retrieved_body ) && isset( $retrieved_body['siteId'] ) ) {
471 update_option( $site_id_key, $retrieved_body['siteId'], 'no' );
472 update_option( "wpins_{$this->plugin_name}_original_url", $site_url, 'no' );
473 update_option( "wpins_{$this->plugin_name}_{$retrieved_body['siteId']}", $body, 'no' );
474 }
475 } else {
476 $failed_data = $body;
477 }
478 }
479
480 $site_id_data_key = "wpins_{$this->plugin_name}_{$site_id}";
481 $site_id_data_failed_key = "wpins_{$this->plugin_name}_{$site_id}_send_failed";
482
483 if ( $site_id != false ) {
484 $old_sent_data = get_option( $site_id_data_key, [] );
485 $diff_data = $this->diff( $body, $old_sent_data );
486 $failed_data = get_option( $site_id_data_failed_key, [] );
487 if ( ! empty( $failed_data ) && $diff_data != $failed_data ) {
488 $failed_data = array_merge( $failed_data, $diff_data );
489 }
490 }
491
492 if ( ! empty( $failed_data ) && $site_id != false ) {
493 $failed_data['plugin_slug'] = $this->plugin_name;
494 $failed_data['url'] = $site_url;
495 $failed_data['site_id'] = $site_id;
496 if ( $original_site_url != false ) {
497 $failed_data['original_url'] = $original_site_url;
498 }
499
500 $request = $this->remote_post( $failed_data );
501 if ( ! is_wp_error( $request ) ) {
502 delete_option( $site_id_data_failed_key );
503 $replaced_data = array_merge( $old_sent_data, $failed_data );
504 update_option( $site_id_data_key, $replaced_data, 'no' );
505 }
506 }
507
508 if ( ! empty( $diff_data ) && $site_id != false && empty( $failed_data ) ) {
509 $diff_data['plugin_slug'] = $this->plugin_name;
510 $diff_data['url'] = $site_url;
511 $diff_data['site_id'] = $site_id;
512 if ( $original_site_url != false ) {
513 $diff_data['original_url'] = $original_site_url;
514 }
515
516 $request = $this->remote_post( $diff_data );
517 if ( is_wp_error( $request ) ) {
518 update_option( $site_id_data_failed_key, $diff_data, 'no' );
519 } else {
520 $replaced_data = array_merge( $old_sent_data, $diff_data );
521 update_option( $site_id_data_key, $replaced_data, 'no' );
522 }
523 }
524
525 $this->set_track_time();
526
527 if ( isset( $request ) && is_wp_error( $request ) ) {
528 return $request;
529 }
530
531 if ( isset( $request ) ) {
532 return true;
533 }
534 return false;
535 }
536 /**
537 * WP_REMOTE_POST method responsible for send data to the API_URL
538 *
539 * @param array $data
540 * @param array $args
541 * @return \WP_Error|array|null
542 */
543 protected function remote_post( $data = array(), $args = array() ) {
544 if ( empty( $data ) ) {
545 return;
546 }
547
548 $args = wp_parse_args(
549 $args,
550 array(
551 'method' => 'POST',
552 'timeout' => 30,
553 'redirection' => 5,
554 'httpversion' => '1.1',
555 'blocking' => true,
556 'body' => $data,
557 'user-agent' => 'PUT/1.0.0; ' . get_bloginfo( 'url' ),
558 )
559 );
560
561 $request = wp_remote_post( esc_url( self::API_URL ), $args );
562 if ( is_wp_error( $request ) || ( isset( $request['response'], $request['response']['code'] ) && $request['response']['code'] != 200 ) ) {
563 return new \WP_Error( 500, 'Something went wrong.' );
564 }
565
566 return $request;
567 }
568 /**
569 * Difference between old and new data
570 *
571 * @param array $new_data
572 * @param array $old_data
573 * @return array
574 */
575 protected function diff( $new_data, $old_data ) {
576 $data = [];
577 if ( ! empty( $new_data ) ) {
578 foreach ( $new_data as $key => $value ) {
579 if ( isset( $old_data[ $key ] ) ) {
580 if ( $old_data[ $key ] == $value ) {
581 continue;
582 }
583 }
584 $data[ $key ] = $value;
585 }
586 }
587 return $data;
588 }
589 /**
590 * Display the admin notice to users to allow them to opt in
591 *
592 * @since 2.5.0
593 */
594 public function notice() {
595 /**
596 * Return if notice is not set.
597 */
598 if ( ! isset( $this->notice_options['notice'] ) ) {
599 return;
600 }
601 /**
602 * Check is allowed or blocked for notice.
603 */
604 $block_notice = get_option( 'wpins_block_notice' );
605 if ( isset( $block_notice[ $this->plugin_name ] ) ) {
606 return;
607 }
608 if ( ! current_user_can( 'manage_options' ) ) {
609 return;
610 }
611
612 $this->has_notice = true;
613
614 $url_yes = add_query_arg(
615 [
616 'plugin' => $this->plugin_name,
617 'plugin_action' => 'yes',
618 ]
619 );
620
621 $url_no = add_query_arg(
622 [
623 'plugin' => $this->plugin_name,
624 'plugin_action' => 'no',
625 ]
626 );
627
628 $url_yes = wp_nonce_url( $url_yes, '_wpnonce_optin_' . $this->plugin_name );
629 $url_no = wp_nonce_url( $url_no, '_wpnonce_optin_' . $this->plugin_name );
630
631 // Decide on notice text
632 $notice_text = $this->notice_options['notice'] . ' <a href="#" class="wpinsights-' . esc_attr( $this->plugin_name ) . '-collect" >' . $this->notice_options['consent_button_text'] . '</a>';
633 $extra_notice_text = $this->notice_options['extra_notice'];
634
635 ?>
636
637 <div class="nx-optin">
638 <p><?php echo wp_kses_post( $notice_text ); ?></p>
639 <div class="wpinsights-data" style="display: none;">
640 <p><?php echo wp_kses_post( $extra_notice_text ); ?></p>
641 </div>
642 <p>
643 <a href="<?php echo esc_url( $url_yes ); ?>" class="button-primary">
644 <?php echo esc_html( $this->notice_options['yes'] ); ?>
645 </a>&nbsp;
646 <a href="<?php echo esc_url( $url_no ); ?>" class="button-secondary">
647 <?php echo esc_html( $this->notice_options['no'] ); ?>
648 </a>
649 </p>
650 </div>
651
652 <?php
653 }
654
655 public function notice_script() {
656 if ( $this->has_notice ) {
657 echo "<script type='text/javascript'>jQuery('.wpinsights-" . esc_attr( $this->plugin_name ) . "-collect').on('click', function(e) {e.preventDefault();jQuery('.wpinsights-data').slideToggle('fast');});</script>";
658 }
659 }
660 /**
661 * Set all notice options to customized notice.
662 *
663 * @since 2.5.0
664 * @param array $options
665 * @return void
666 */
667 public function set_notice_options( $options = [] ) {
668 $default_options = [
669 'consent_button_text' => __( 'What we collect.', 'betterdocs' ),
670 'yes' => __( 'Sure, I\'d like to help', 'betterdocs' ),
671 'no' => __( 'No Thanks.', 'betterdocs' ),
672 ];
673 $options = wp_parse_args( $options, $default_options );
674 $this->notice_options = $options;
675 }
676 /**
677 * Responsible for track the click from Notice.
678 *
679 * @return void
680 */
681 public function clicked( $notice = null ) {
682 if ( isset( $_GET['_wpnonce'] ) && isset( $_GET['plugin'] ) && isset( $_GET['plugin_action'] ) ) {
683 $tab = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : '';
684 if ( 'plugin-information' === $tab ) {
685 return;
686 }
687
688 $nonce = sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) );
689 if ( ! wp_verify_nonce( $nonce, '_wpnonce_optin_' . $this->plugin_name ) ) {
690 return;
691 }
692
693 $plugin = sanitize_text_field( wp_unslash( $_GET['plugin'] ) );
694 $action = sanitize_text_field( wp_unslash( $_GET['plugin_action'] ) );
695 if ( $action == 'yes' ) {
696 $this->schedule_tracking();
697 $this->set_is_tracking_allowed( true, $plugin );
698 if ( $this->do_tracking( true ) ) {
699 $this->update_block_notice( $plugin );
700 }
701 } else {
702 $this->set_is_tracking_allowed( false, $plugin );
703 $this->update_block_notice( $plugin );
704 }
705
706 if ( ! is_null( $notice ) ) {
707 $notice->dismiss->dismiss_notice();
708 }
709
710 /**
711 * Redirect User To the Current URL, but without set query arguments.
712 */
713 wp_safe_redirect( $this->redirect_to() );
714 }
715 }
716 /**
717 * Set if we should block the opt-in notice for this plugin
718 *
719 * @since 2.5.0
720 */
721 public function update_block_notice( $plugin = null ) {
722 if ( empty( $plugin ) ) {
723 $plugin = $this->plugin_name;
724 }
725 $block_notice = get_option( 'wpins_block_notice' );
726 if ( empty( $block_notice ) || ! is_array( $block_notice ) ) {
727 $block_notice = array( $plugin => $plugin );
728 } else {
729 $block_notice[ $plugin ] = $plugin;
730 }
731 update_option( 'wpins_block_notice', $block_notice, 'no' );
732 }
733 /**
734 * AJAX callback when the deactivated form is submitted.
735 *
736 * @since 2.5.0
737 */
738 public function deactivate_reasons_form_submit() {
739 check_ajax_referer( 'wpins_deactivation_nonce', 'security' );
740 if ( isset( $_POST['values'] ) ) {
741 $values = sanitize_text_field( wp_unslash( $_POST['values'] ) );
742 update_option( 'wpins_deactivation_reason_' . $this->plugin_name, $values );
743 }
744 if ( isset( $_POST['details'] ) ) {
745 $details = sanitize_text_field( wp_unslash( $_POST['details'] ) );
746 update_option( 'wpins_deactivation_details_' . $this->plugin_name, $details );
747 }
748 wp_die();
749 }
750 /**
751 * Filter the deactivation link to allow us to present a form when the user deactivates the plugin
752 *
753 * @since 2.5.0
754 */
755 public function deactivate_action_links( $links ) {
756 /**
757 * Check is tracking allowed or not.
758 */
759 if ( ! $this->is_tracking_allowed() ) {
760 return $links;
761 }
762 if ( isset( $links['deactivate'] ) && $this->include_goodbye_form ) {
763 $deactivation_link = $links['deactivate'];
764 /**
765 * Change the default deactivate button link.
766 */
767 $deactivation_link = str_replace( '<a ', '<div class="wpinsights-goodbye-form-wrapper-' . esc_attr( $this->plugin_name ) . '"><div class="wpinsights-goodbye-form-bg"></div><span class="wpinsights-goodbye-form" id="wpinsights-goodbye-form"></span></div><a onclick="javascript:event.preventDefault();" id="wpinsights-goodbye-link-' . esc_attr( $this->plugin_name ) . '" ', $deactivation_link );
768 $links['deactivate'] = $deactivation_link;
769 }
770 return $links;
771 }
772 /**
773 * ALL Deactivate Reasons.
774 *
775 * @since 2.5.0
776 */
777 public function deactivation_reasons() {
778 $form = array();
779 $form['heading'] = __( 'We Value Your Feedback', 'betterdocs' );
780 $form['body'] = __( "Could you please tell us why you're deactivating our plugin? Your insights will help us to improve.", 'betterdocs' );
781
782 $form['options'] = array(
783 __( 'I no longer need the plugin', 'betterdocs' ),
784 [
785 'label' => __( 'I found a better plugin', 'betterdocs' ),
786 'extra_field' => __( 'Please share which plugin', 'betterdocs' )
787 ],
788 __( "I couldn't get the plugin to work", 'betterdocs' ),
789 __( 'It\'s a temporary deactivation', 'betterdocs' ),
790 [
791 'label' => __( 'Other', 'betterdocs' ),
792 'extra_field' => __( 'Please share the reason', 'betterdocs' ),
793 'type' => 'textarea'
794 ]
795 );
796 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- WP Insights (appsero) library hook; name is defined by the upstream tracker library.
797 return apply_filters( 'wpins_form_text_' . $this->plugin_name, $form );
798 }
799
800 /**
801 * Deactivate Reasons Form.
802 * This form will appears when user wants to deactivate the plugin to send you deactivated reasons.
803 *
804 * @since 3.0.0
805 */
806 public function deactivate_reasons_form() {
807 $form = $this->deactivation_reasons();
808 $class_plugin_name = esc_attr( $this->plugin_name );
809 $html = '<div class="betterdocs__modal-close-btn"><svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M5.29289 5.29289C5.68342 4.90237 6.31658 4.90237 6.70711 5.29289L12 10.5858L17.2929 5.29289C17.6834 4.90237 18.3166 4.90237 18.7071 5.29289C19.0976 5.68342 19.0976 6.31658 18.7071 6.70711L13.4142 12L18.7071 17.2929C19.0976 17.6834 19.0976 18.3166 18.7071 18.7071C18.3166 19.0976 17.6834 19.0976 17.2929 18.7071L12 13.4142L6.70711 18.7071C6.31658 19.0976 5.68342 19.0976 5.29289 18.7071C4.90237 18.3166 4.90237 17.6834 5.29289 17.2929L10.5858 12L5.29289 6.70711C4.90237 6.31658 4.90237 5.68342 5.29289 5.29289Z"/></svg></div><div class="wpinsights-goodbye-form-head"><span><svg width="65" height="64" viewBox="0 0 65 64" fill="none" xmlns="http://www.w3.org/2000/svg"><rect x="0.5" width="64" height="64" rx="16" fill="#e0fff6"/><path d="M41.8346 22.668L45.8346 18.668M19.168 45.3346L23.168 41.3346M26.5013 34.0013L29.8346 30.668M30.5013 38.0013L33.8346 34.668M24.9013 43.068C25.1986 43.3663 25.5518 43.603 25.9408 43.7645C26.3298 43.926 26.7468 44.0092 27.168 44.0092C27.5891 44.0092 28.0062 43.926 28.3951 43.7645C28.7841 43.603 29.1373 43.3663 29.4346 43.068L32.5013 40.0013L24.5013 32.0013L21.4346 35.068C21.1363 35.3653 20.8996 35.7185 20.7381 36.1075C20.5766 36.4964 20.4934 36.9135 20.4934 37.3346C20.4934 37.7558 20.5766 38.1728 20.7381 38.5618C20.8996 38.9508 21.1363 39.304 21.4346 39.6013L24.9013 43.068ZM32.5013 24.0013L40.5013 32.0013L43.568 28.9346C43.8663 28.6373 44.103 28.2841 44.2645 27.8951C44.426 27.5062 44.5092 27.0891 44.5092 26.668C44.5092 26.2468 44.426 25.8298 44.2645 25.4408C44.103 25.0518 43.8663 24.6986 43.568 24.4013L40.1013 20.9346C39.804 20.6363 39.4508 20.3996 39.0618 20.2381C38.6728 20.0766 38.2558 19.9934 37.8346 19.9934C37.4135 19.9934 36.9964 20.0766 36.6075 20.2381C36.2185 20.3996 35.8653 20.6363 35.568 20.9346L32.5013 24.0013Z" stroke="#00b884" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg></span><h1>' . $form['heading'] . '</h1></div>';
810 $html .= '<div class="wpinsights-goodbye-form-body"><p class="wpinsights-goodbye-form-caption">' . esc_html( $form['body'] ) . '</p>';
811 if ( is_array( $form['options'] ) ) {
812 $html .= '<div id="wpinsights-goodbye-options" class="wpinsights-goodbye-options"><ul>';
813 foreach ( $form['options'] as $option ) {
814 if ( is_array( $option ) ) {
815 $id = strtolower( str_replace( ' ', '_', esc_attr( $option['label'] ) ) );
816 $id = $id . '_' . $class_plugin_name;
817 $html .= '<li class="has-goodbye-extra">';
818 $html .= '<input type="radio" name="wpinsights-' . esc_attr( $class_plugin_name ) . '-goodbye-options" id="' . esc_attr( $id ) . '" value="' . esc_attr( $option['label'] ) . '">';
819 $html .= '<div><label for="' . $id . '">' . esc_attr( $option['label'] ) . '</label>';
820 if ( isset( $option['extra_field'] ) && ! isset( $option['type'] ) ) {
821 $html .= '<input type="text" style="display: none" name="' . esc_attr( $id ) . '" id="' . str_replace( ' ', '', esc_attr( $option['extra_field'] ) ) . '" placeholder="' . esc_attr( $option['extra_field'] ) . '">';
822 }
823 if ( isset( $option['extra_field'] ) && isset( $option['type'] ) ) {
824 $html .= '<' . $option['type'] . ' style="display: none" type="text" name="' . esc_attr( $id ) . '" id="' . str_replace( ' ', '', esc_attr( $option['extra_field'] ) ) . '" placeholder="' . esc_attr( $option['extra_field'] ) . '"></' . $option['type'] . '>';
825 }
826 $html .= '</div></li>';
827 } else {
828 $id = strtolower( str_replace( ' ', '_', esc_attr( $option ) ) );
829 $id = $id . '_' . $class_plugin_name;
830 $html .= '<li><input type="radio" name="wpinsights-' . $class_plugin_name . '-goodbye-options" id="' . esc_attr( $id ) . '" value="' . esc_attr( $option ) . '"> <label for="' . $id . '">' . esc_attr( $option ) . '</label></li>';
831 }
832 }
833 $html .= '</ul></div><!-- .wpinsights-' . $class_plugin_name . '-goodbye-options -->';
834 }
835 $html .= '</div><!-- .wpinsights-goodbye-form-body -->';
836 $html .= '<p class="deactivating-spinner"><span class="spinner"></span> ' . __( 'Submitting form', 'betterdocs' ) . '</p>';
837
838 $wrapper_class = '.wpinsights-goodbye-form-wrapper-' . $class_plugin_name;
839
840 $styles = '';
841 $styles .= '<style type="text/css">';
842 $styles .= '.wpinsights-form-active-' . $class_plugin_name . ' .wpinsights-goodbye-form-bg {';
843 $styles .= 'background: rgba( 0, 0, 0, .8 );position: fixed;top: 0;left: 0;width: 100%;height: 100%;z-index: 9;';
844 $styles .= '}';
845 $styles .= $wrapper_class . '{';
846 $styles .= 'position: relative; display: none;';
847 $styles .= '}';
848 $styles .= '.wpinsights-form-active-' . $class_plugin_name . ' ' . $wrapper_class . '{';
849 $styles .= 'display: flex !important; position: fixed;top: 0;left: 0;width: 100%;height: 100%; justify-content: center; align-items: center;';
850 $styles .= '}';
851 $styles .= $wrapper_class . ' .wpinsights-goodbye-form { display: none; }';
852 $styles .= '.wpinsights-form-active-' . $class_plugin_name . ' .wpinsights-goodbye-form {';
853 $styles .= 'position: relative !important; width: 550px; max-width: 80%; background: #fff; box-shadow: 2px 8px 23px 3px rgba(0,0,0,.2); border-radius: 3px; white-space: normal; overflow: hidden; display: block; z-index: 999999;';
854 $styles .= '}';
855 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-head {';
856 $styles .= 'background: #fff; color: #495157; padding: 18px; box-shadow: 0 0 8px rgba(0,0,0,.1); font-size: 15px;';
857 $styles .= '}';
858 $styles .= $wrapper_class . ' .wpinsights-goodbye-form .wpinsights-goodbye-form-head strong { font-size: 15px; }';
859 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body { padding: 8px 18px; color: #333; }';
860 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body label { padding-left: 5px; color: #6d7882; }';
861 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body .wpinsights-goodbye-form-caption {';
862 $styles .= 'font-weight: 500; font-size: 15px; color: #495157; line-height: 1.4;';
863 $styles .= '}';
864 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body #wpinsights-goodbye-options { padding-top: 5px; }';
865 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li { margin-bottom: 15px; }';
866 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li > div { display: inline; padding-left: 3px; }';
867 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li > div > input, ' . $wrapper_class . ' .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li > div > textarea {';
868 $styles .= 'margin: 10px 18px; padding: 8px; width: 80%;';
869 $styles .= '}';
870 $styles .= $wrapper_class . ' .deactivating-spinner { display: none; padding-bottom: 20px !important; }';
871 $styles .= $wrapper_class . ' .deactivating-spinner .spinner { float: none; margin: 4px 4px 0 18px; vertical-align: bottom; visibility: visible; }';
872 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer { padding: 8px 18px; margin-bottom: 15px; }';
873 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer > .wpinsights-goodbye-form-buttons { display: flex; align-items: center; justify-content: space-between; }';
874 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer .wpinsights-submit-btn {';
875 $styles .= 'background-color: #f3bafd; -webkit-border-radius: 3px; border-radius: 3px; color: #0c0d0e; line-height: 1; padding: 10px 20px; font-size: 13px; font-weight: 500; text-transform: uppercase; transition: .3s;';
876 $styles .= '}';
877 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer .wpinsights-submit-btn:hover {';
878 $styles .= 'background-color: #f5d0fe;';
879 $styles .= '}';
880 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer .wpinsights-deactivate-btn {';
881 $styles .= 'font-size: 13px; color: #a4afb7; background: none; float: right; padding-right: 10px; width: auto; text-decoration: underline;';
882 $styles .= '}';
883 $styles .= $wrapper_class . ' .test {';
884 $styles .= '}';
885 $styles .= '
886
887 .wpinsights-form-active-betterdocs .wpinsights-goodbye-form-wrapper-betterdocs {
888 display: flex !important;
889 position: fixed;
890 top: 0;
891 left: 0;
892 right: 0;
893 bottom: 0;
894 width: 100%;
895 z-index: 9999;
896 height: 100%;
897 justify-content: center;
898 align-items: center;
899 }
900 .wpinsights-form-active-betterdocs .wpinsights-goodbye-form {
901 border-radius: 8px;
902 width: 563px;
903 overflow: visible;
904 position: relative;
905 }
906 .wpinsights-goodbye-form .betterdocs__modal-close-btn {
907 position: absolute;
908 top: 0;
909 right: -55px;
910 width: 40px;
911 height: 40px;
912 background: #fff;
913 border-radius: 50%;
914 display: flex;
915 justify-content: center;
916 align-items: center;
917 font-size: 12px;
918 font-weight: 500;
919 color: #475467;
920 cursor: pointer;
921 }
922 .wpinsights-goodbye-form .betterdocs__modal-close-btn svg {
923 width: 20px;
924 }
925 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-head {
926 background: #fff;
927 color: #495157;
928 padding: 24px;
929 border-radius: 8px 8px 0 0;
930 box-shadow: none;
931 border-bottom: 1px solid #EAECF0;
932 display: flex;
933 flex-direction: column;
934 gap: 16px;
935 align-items: center;
936 }
937 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-head > span {
938 display: inline-flex;
939 }
940 .wpinsights-goodbye-form-head h1 {
941 font-size: 22px;
942 font-weight: 450;
943 color: #1D2939;
944 padding: 0;
945 }
946 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body {
947 padding: 32px 40px;
948 max-height: calc(70vh - 230px);
949 overflow: auto;
950 }
951 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body .wpinsights-goodbye-form-caption {
952 font-size: 18px;
953 color: #1D2939;
954 margin: 0;
955 padding-bottom: 16px;
956 font-weight: 400;
957 }
958 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body #wpinsights-goodbye-options {
959 padding-top: 0px;
960 }
961 .wpinsights-goodbye-form-wrapper-betterdocs .widefat td ul {
962 font-size: 14px;
963 margin: 0;
964 color: #475467;
965 line-height: 1.4em;
966 }
967 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li:not(:last-child) {
968 margin-bottom: 16px;
969 }
970 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li:last-child {
971 margin-bottom: 0;
972 }
973 .wpinsights-goodbye-form-wrapper-betterdocs input[type=radio] {
974 border-radius: 50%;
975 margin-right: .25rem;
976 line-height: .71428571;
977 margin: 0;
978 }
979 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body label {
980 padding-left: 4px;
981 color: #475467;
982 font-size: 14px;
983 }
984 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li > div > input, .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li > div > textarea {
985 padding: 10px 16px;
986 border-radius: 8px;
987 width: 100%;
988 border: 1px solid #D0D5DD;
989 margin: 0;
990 margin-top: 16px;
991 color: #1D2939;
992 font-size: 14px;
993 line-height: 1.5em;
994 resize: none;
995 max-height: 44px;
996 }
997 .wpinsights-goodbye-form-wrapper-betterdocs input[type=radio] {
998 border: 1px solid #D0D5DD;
999 box-shadow: none;
1000 }
1001 .wpinsights-goodbye-form-wrapper-betterdocs input[type=radio]:checked::before {
1002 content: "";
1003 border-radius: 50%;
1004 width: .88rem;
1005 height: .88rem;
1006 margin: -.95px;
1007 background-color: #00b884;
1008 border: 1px solid #e0fff6;
1009 line-height: 1.14285714;
1010 outline: 0;
1011 }
1012 .wpinsights-goodbye-form-wrapper-betterdocs input[type=radio]:focus {
1013 border-color: #D0D5DD;
1014 box-shadow: none;
1015 outline: 0;
1016 }
1017 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li > div > input::placeholder,
1018 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li > div > textarea::placeholder{
1019 color: #C6CBD2 !important;
1020 }
1021 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-footer {
1022 padding: 16px 36px;
1023 margin-bottom: 0;
1024 border-top: 1px solid #EAECF0;
1025 }
1026 .wpinsights-goodbye-form-wrapper-betterdocs input:focus,
1027 .wpinsights-goodbye-form-wrapper-betterdocs textarea:focus {
1028 box-shadow: none !important;
1029 outline: 0 !important;
1030 }
1031 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-footer > .wpinsights-goodbye-form-buttons {
1032 display: flex;
1033 align-items: center;
1034 justify-content: flex-start;
1035 }
1036 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-footer .wpinsights-submit-btn {
1037 background-color: #00b884;
1038 -webkit-border-radius: 8px;
1039 border-radius: 8px;
1040 color: #fff;
1041 padding: 8px 16px;
1042 font-size: 14px;
1043 font-weight: 500;
1044 line-height: 1.5em;
1045 text-transform: capitalize;
1046 transition: .3s;
1047 }
1048 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-footer .wpinsights-submit-btn:hover {
1049 background: #00b884;
1050 }
1051
1052 .wpinsights-goodbye-form-wrapper-betterdocs .wpinsights-goodbye-form-footer .wpsp-put-deactivate-btn {
1053 font-size: 14px;
1054 font-weight: 500;
1055 color: #344054;
1056 margin-left: 10px;
1057 }
1058 .wp-person a:focus .gravatar, a:focus, a:focus .media-icon img, a:focus .plugin-icon {
1059 color: #043959;
1060 box-shadow: none;
1061 outline: 0;
1062 }
1063
1064 ';
1065 $styles .= '</style>';
1066 $styles .= '';
1067
1068 echo $styles; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- This is styles, which is why escaping is not needed
1069
1070 ?>
1071 <script type="text/javascript">
1072 jQuery(document).ready(function($){
1073 $("#wpinsights-goodbye-link-<?php echo esc_attr( $class_plugin_name ); ?>").on("click",function(){
1074 // We'll send the user to this deactivation link when they've completed or dismissed the form
1075 var url = document.getElementById("wpinsights-goodbye-link-<?php echo esc_attr( $class_plugin_name ); ?>");
1076 $('body').toggleClass('wpinsights-form-active-<?php echo esc_attr( $class_plugin_name ); ?>');
1077 $(".wpinsights-goodbye-form-wrapper-<?php echo esc_attr( $class_plugin_name ); ?> #wpinsights-goodbye-form").fadeIn();
1078 $(".wpinsights-goodbye-form-wrapper-<?php echo esc_attr( $class_plugin_name ); ?> #wpinsights-goodbye-form").html( '<?php echo $html; //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- This is an html, not needed to escape ?>' + '<div class="wpinsights-goodbye-form-footer"><div class="wpinsights-goodbye-form-buttons"><a id="wpinsights-submit-form-<?php echo esc_attr( $class_plugin_name ); ?>" class="wpinsights-submit-btn" href="#"><?php esc_html_e( 'Submit and Deactivate', 'betterdocs' ); ?></a>&nbsp;<a class="wpsp-put-deactivate-btn" href="'+url+'"><?php esc_html_e( 'Just Deactivate', 'betterdocs' ); ?></a></div></div>');
1079 $('#wpinsights-submit-form-<?php echo esc_attr( $class_plugin_name ); ?>').on('click', function(e){
1080 // As soon as we click, the body of the form should disappear
1081 $("#wpinsights-goodbye-form-<?php echo esc_attr( $class_plugin_name ); ?> .wpinsights-goodbye-form-body").fadeOut();
1082 $("#wpinsights-goodbye-form-<?php echo esc_attr( $class_plugin_name ); ?> .wpinsights-goodbye-form-footer").fadeOut();
1083 // Fade in spinner
1084 $("#wpinsights-goodbye-form-<?php echo esc_attr( $class_plugin_name ); ?> .deactivating-spinner").fadeIn();
1085 e.preventDefault();
1086 var checkedInput = $("input[name='wpinsights-<?php echo esc_attr( $class_plugin_name ); ?>-goodbye-options']:checked"),
1087 checkedInputVal, details;
1088 if( checkedInput.length > 0 ) {
1089 checkedInputVal = checkedInput.val();
1090 details = $('input[name="'+ checkedInput[0].id +'"], textarea[name="'+ checkedInput[0].id +'"]').val();
1091 }
1092
1093 if( typeof details === 'undefined' ) {
1094 details = '';
1095 }
1096 if( typeof checkedInputVal === 'undefined' ) {
1097 checkedInputVal = 'No Reason';
1098 }
1099
1100 var data = {
1101 'action': 'deactivation_form_<?php echo esc_attr( $class_plugin_name ); ?>',
1102 'values': checkedInputVal,
1103 'details': details,
1104 'security': "<?php echo wp_create_nonce( 'wpins_deactivation_nonce' ); //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>",
1105 'dataType': "json"
1106 }
1107
1108 $.post(
1109 ajaxurl,
1110 data,
1111 function(response){
1112 // Redirect to original deactivation URL
1113 window.location.href = url;
1114 }
1115 );
1116 });
1117 $('#wpinsights-goodbye-options > ul ').on('click', 'li label, li > input', function( e ){
1118 var parent = $(this).parents('li');
1119 parent.siblings().find('label').next('input, textarea').css('display', 'none');
1120 parent.find('label').next('input, textarea').css('display', 'block');
1121 });
1122 // If we click outside the form, the form will close
1123 $('.wpinsights-goodbye-form-bg, #wpinsights-goodbye-form > .betterdocs__modal-close-btn').on('click',function(){
1124 $("#wpinsights-goodbye-form").fadeOut();
1125 $('body').removeClass('wpinsights-form-active-<?php echo esc_attr( $class_plugin_name ); ?>');
1126 });
1127 });
1128 });
1129 </script>
1130 <?php
1131 }
1132 }
1133