PluginProbe
weForms – Easy Drag & Drop Contact Form Builder For WordPress / 1.6.1
weForms – Easy Drag & Drop Contact Form Builder For WordPress v1.6.1
1.6.7 1.6.8 1.6.9 1.6.12 1.6.13 1.6.14 1.6.15 1.6.16 1.6.17 1.6.18 1.6.19 1.6.2 1.6.20 1.6.21 1.6.22 1.6.23 1.6.24 1.6.25 1.6.26 1.6.27 1.6.28 1.6.3 1.6.4 1.6.5 1.6.6 All 74 releases
weforms / includes / library / appsero / Insights.php

Insights.php in weForms – Easy Drag & Drop Contact Form Builder For WordPress 1.6.1, at includes/library/appsero/Insights.php

917 lines 29.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Appsero;
3
4 /**
5 * Appsero Insights
6 *
7 * This is a tracker class to track plugin usage based on if the customer has opted in.
8 * No personal information is being tracked by this class, only general settings, active plugins, environment details
9 * and admin email.
10 */
11 class Insights {
12
13 /**
14 * The notice text
15 *
16 * @var string
17 */
18 public $notice;
19
20 /**
21 * Wheather to the notice or not
22 *
23 * @var boolean
24 */
25 protected $show_notice = true;
26
27 /**
28 * If extra data needs to be sent
29 *
30 * @var array
31 */
32 protected $extra_data = array();
33
34 /**
35 * AppSero\Client
36 *
37 * @var object
38 */
39 protected $client;
40
41 /**
42 * Initialize the class
43 *
44 * @param AppSero\Client
45 */
46 public function __construct( $client, $name = null, $file = null ) {
47
48 if ( is_string( $client ) && ! empty( $name ) && ! empty( $file ) ) {
49 $client = new Client( $client, $name, $file );
50 }
51
52 if ( is_object( $client ) && is_a( $client, 'Appsero\Client' ) ) {
53 $this->client = $client;
54 }
55 }
56
57 /**
58 * Don't show the notice
59 *
60 * @return \self
61 */
62 public function hide_notice() {
63 $this->show_notice = false;
64
65 return $this;
66 }
67
68 /**
69 * Add extra data if needed
70 *
71 * @param array $data
72 *
73 * @return \self
74 */
75 public function add_extra( $data = array() ) {
76 $this->extra_data = $data;
77
78 return $this;
79 }
80
81 /**
82 * Set custom notice text
83 *
84 * @param string $text
85 *
86 * @return \self
87 */
88 public function notice( $text ) {
89 $this->notice = $text;
90
91 return $this;
92 }
93
94 /**
95 * Initialize insights
96 *
97 * @return void
98 */
99 public function init() {
100 if ( $this->client->type == 'plugin' ) {
101 $this->init_plugin();
102 } else if ( $this->client->type == 'theme' ) {
103 $this->init_theme();
104 }
105 }
106
107 /**
108 * Initialize theme hooks
109 *
110 * @return void
111 */
112 public function init_theme() {
113 $this->init_common();
114
115 add_action( 'switch_theme', array( $this, 'deactivation_cleanup' ) );
116 add_action( 'switch_theme', array( $this, 'theme_deactivated' ), 12, 3 );
117 }
118
119 /**
120 * Initialize plugin hooks
121 *
122 * @return void
123 */
124 public function init_plugin() {
125 // plugin deactivate popup
126 if ( ! $this->is_local_server() ) {
127 add_filter( 'plugin_action_links_' . $this->client->basename, array( $this, 'plugin_action_links' ) );
128 add_action( 'admin_footer', array( $this, 'deactivate_scripts' ) );
129 }
130
131 $this->init_common();
132
133 register_activation_hook( $this->client->file, array( $this, 'activate_plugin' ) );
134 register_deactivation_hook( $this->client->file, array( $this, 'deactivation_cleanup' ) );
135 }
136
137 /**
138 * Initialize common hooks
139 *
140 * @return void
141 */
142 protected function init_common() {
143
144 if ( $this->show_notice ) {
145 // tracking notice
146 add_action( 'admin_notices', array( $this, 'admin_notice' ) );
147 }
148
149 add_action( 'admin_init', array( $this, 'handle_optin_optout' ) );
150
151 // uninstall reason
152 add_action( 'wp_ajax_' . $this->client->slug . '_submit-uninstall-reason', array( $this, 'uninstall_reason_submission' ) );
153
154 // cron events
155 add_filter( 'cron_schedules', array( $this, 'add_weekly_schedule' ) );
156 add_action( $this->client->slug . '_tracker_send_event', array( $this, 'send_tracking_data' ) );
157 // add_action( 'admin_init', array( $this, 'send_tracking_data' ) ); // test
158 }
159
160 /**
161 * Send tracking data to AppSero server
162 *
163 * @param boolean $override
164 *
165 * @return void
166 */
167 public function send_tracking_data( $override = false ) {
168 // skip on AJAX Requests
169 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
170 return;
171 }
172
173 if ( ! $this->tracking_allowed() && ! $override ) {
174 return;
175 }
176
177 // Send a maximum of once per week
178 $last_send = $this->get_last_send();
179
180 if ( $last_send && $last_send > strtotime( '-1 week' ) ) {
181 return;
182 }
183
184 $response = $this->client->send_request( $this->get_tracking_data(), 'track' );
185
186 update_option( $this->client->slug . '_tracking_last_send', time() );
187 }
188
189 /**
190 * Get the tracking data points
191 *
192 * @return array
193 */
194 protected function get_tracking_data() {
195 $all_plugins = $this->get_all_plugins();
196
197 $users = get_users( array(
198 'role' => 'administrator',
199 'orderby' => 'ID',
200 'order' => 'ASC',
201 'number' => 1,
202 'paged' => 1,
203 ) );
204
205 $admin_user = ( is_array( $users ) && ! empty( $users ) ) ? $users[0] : false;
206 $first_name = $last_name = '';
207
208 if ( $admin_user ) {
209 $first_name = $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name;
210 $last_name = $admin_user->last_name;
211 }
212
213 $data = array(
214 'version' => $this->client->project_version,
215 'url' => esc_url( home_url() ),
216 'site' => $this->get_site_name(),
217 'admin_email' => get_option( 'admin_email' ),
218 'first_name' => $first_name,
219 'last_name' => $last_name,
220 'hash' => $this->client->hash,
221 'server' => $this->get_server_info(),
222 'wp' => $this->get_wp_info(),
223 'users' => $this->get_user_counts(),
224 'active_plugins' => count( $all_plugins['active_plugins'] ),
225 'inactive_plugins' => count( $all_plugins['inactive_plugins'] ),
226 'ip_address' => $this->get_user_ip_address(),
227 'theme' => get_stylesheet(),
228 'version' => $this->client->project_version,
229 );
230
231 // Add metadata
232 if ( $extra = $this->get_extra_data() ) {
233 $data['extra'] = $extra;
234 }
235
236 return apply_filters( $this->client->slug . '_tracker_data', $data );
237 }
238
239 /**
240 * If a child class wants to send extra data
241 *
242 * @return mixed
243 */
244 protected function get_extra_data() {
245 if ( is_callable( $this->extra_data ) ) {
246 return call_user_func( $this->extra_data );
247 }
248
249 if ( is_array( $this->extra_data ) ) {
250 return $this->extra_data;
251 }
252
253 return array();
254 }
255
256 /**
257 * Explain the user which data we collect
258 *
259 * @return string
260 */
261 protected function data_we_collect() {
262 $data = array(
263 'Server environment details (php, mysql, server, WordPress versions)',
264 'Number of users in your site',
265 'Site language',
266 'Number of active and inactive plugins',
267 'Site name and url',
268 'Your name and email address',
269 );
270
271 return $data;
272 }
273
274 /**
275 * Check if the user has opted into tracking
276 *
277 * @return bool
278 */
279 public function tracking_allowed() {
280 $allow_tracking = get_option( $this->client->slug . '_allow_tracking', 'no' );
281
282 return $allow_tracking == 'yes';
283 }
284
285 /**
286 * Get the last time a tracking was sent
287 *
288 * @return false|string
289 */
290 private function get_last_send() {
291 return get_option( $this->client->slug . '_tracking_last_send', false );
292 }
293
294 /**
295 * Check if the notice has been dismissed or enabled
296 *
297 * @return boolean
298 */
299 private function notice_dismissed() {
300 $version = get_option( $this->client->slug . '_hide_fortressdb_version', null );
301 $current_version = get_option( 'weforms_version' );
302
303 if ( $version && version_compare( $current_version, $version, '<=' ) ) {
304 return true;
305 }
306
307 return false;
308 }
309
310 /**
311 * Check if the current server is localhost
312 *
313 * @return boolean
314 */
315 private function is_local_server() {
316 return false;
317
318 $is_local = in_array( $_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1' ) );
319
320 return apply_filters( 'appsero_is_local', $is_local );
321 }
322
323 /**
324 * Schedule the event weekly
325 *
326 * @return void
327 */
328 private function schedule_event() {
329 $hook_name = $this->client->slug . '_tracker_send_event';
330
331 if ( ! wp_next_scheduled( $hook_name ) ) {
332 wp_schedule_event( time(), 'weekly', $hook_name );
333 }
334 }
335
336 /**
337 * Clear any scheduled hook
338 *
339 * @return void
340 */
341 private function clear_schedule_event() {
342 wp_clear_scheduled_hook( $this->client->slug . '_tracker_send_event' );
343 }
344
345 /**
346 * Display the admin notice to users that have not opted-in or out
347 *
348 * @return void
349 */
350 public function admin_notice() {
351
352 if ( $this->notice_dismissed() ) {
353 return;
354 }
355
356 if ( ! current_user_can( 'manage_options' ) ) {
357 return;
358 }
359
360 // don't show tracking if a local server
361 if ( ! $this->is_local_server() ) {
362 $learn_url = admin_url('admin.php?page=weforms#/settings');
363 $optout_url = add_query_arg( $this->client->slug . '_hide_fortressdb', 'true' );
364
365 if ( empty( $this->notice ) ) {
366 $notice = sprintf( __( "Want to better secure your contact form's valuable data? Check out FortressDB!", $this->client->textdomain, 'weforms' ), $this->client->name );
367 } else {
368 $notice = $this->notice;
369 }
370
371 echo '<div class="updated"><p>';
372 echo $notice;
373 echo '</p><p class="submit">';
374 echo '&nbsp;<a href="' . esc_url( $learn_url ) . '" class="button-primary button-large">' . __( 'Learn More', $this->client->textdomain, 'weforms' ) . '</a>';
375 echo '&nbsp;<a href="' . esc_url( $optout_url ) . '" class="button-secondary button-large">' . __( 'Hide', $this->client->textdomain, 'weforms' ) . '</a>';
376 echo '</p></div>';
377 }
378 }
379
380 /**
381 * handle the optin/optout
382 *
383 * @return void
384 */
385 public function handle_optin_optout() {
386
387 if ( isset( $_GET[ $this->client->slug . '_hide_fortressdb' ] ) && $_GET[ $this->client->slug . '_hide_fortressdb' ] == 'true' ) {
388 $current_version = get_option( 'weforms_version' );
389 update_option( $this->client->slug . '_hide_fortressdb_version', $current_version );
390
391 wp_redirect( remove_query_arg( $this->client->slug . '_hide_fortressdb' ) );
392 exit;
393 }
394 }
395
396 /**
397 * Get the number of post counts
398 *
399 * @param string $post_type
400 *
401 * @return integer
402 */
403 public function get_post_count( $post_type ) {
404 global $wpdb;
405
406 return (int) $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts WHERE post_type = '$post_type' and post_status = 'publish'");
407 }
408
409 /**
410 * Get server related info.
411 *
412 * @return array
413 */
414 private static function get_server_info() {
415 global $wpdb;
416
417 $server_data = array();
418
419 if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) {
420 $server_data['software'] = $_SERVER['SERVER_SOFTWARE'];
421 }
422
423 if ( function_exists( 'phpversion' ) ) {
424 $server_data['php_version'] = phpversion();
425 }
426
427 $server_data['mysql_version'] = $wpdb->db_version();
428
429 $server_data['php_max_upload_size'] = size_format( wp_max_upload_size() );
430 $server_data['php_default_timezone'] = date_default_timezone_get();
431 $server_data['php_soap'] = class_exists( 'SoapClient' ) ? 'Yes' : 'No';
432 $server_data['php_fsockopen'] = function_exists( 'fsockopen' ) ? 'Yes' : 'No';
433 $server_data['php_curl'] = function_exists( 'curl_init' ) ? 'Yes' : 'No';
434
435 return $server_data;
436 }
437
438 /**
439 * Get WordPress related data.
440 *
441 * @return array
442 */
443 private function get_wp_info() {
444 $wp_data = array();
445
446 $wp_data['memory_limit'] = WP_MEMORY_LIMIT;
447 $wp_data['debug_mode'] = ( defined('WP_DEBUG') && WP_DEBUG ) ? 'Yes' : 'No';
448 $wp_data['locale'] = get_locale();
449 $wp_data['version'] = get_bloginfo( 'version' );
450 $wp_data['multisite'] = is_multisite() ? 'Yes' : 'No';
451
452 return $wp_data;
453 }
454
455 /**
456 * Get the list of active and inactive plugins
457 *
458 * @return array
459 */
460 private function get_all_plugins() {
461 // Ensure get_plugins function is loaded
462 if ( ! function_exists( 'get_plugins' ) ) {
463 include ABSPATH . '/wp-admin/includes/plugin.php';
464 }
465
466 $plugins = get_plugins();
467 $active_plugins_keys = get_option( 'active_plugins', array() );
468 $active_plugins = array();
469
470 foreach ( $plugins as $k => $v ) {
471 // Take care of formatting the data how we want it.
472 $formatted = array();
473 $formatted['name'] = strip_tags( $v['Name'] );
474
475 if ( isset( $v['Version'] ) ) {
476 $formatted['version'] = strip_tags( $v['Version'] );
477 }
478
479 if ( isset( $v['Author'] ) ) {
480 $formatted['author'] = strip_tags( $v['Author'] );
481 }
482
483 if ( isset( $v['Network'] ) ) {
484 $formatted['network'] = strip_tags( $v['Network'] );
485 }
486
487 if ( isset( $v['PluginURI'] ) ) {
488 $formatted['plugin_uri'] = strip_tags( $v['PluginURI'] );
489 }
490
491 if ( in_array( $k, $active_plugins_keys ) ) {
492 // Remove active plugins from list so we can show active and inactive separately
493 unset( $plugins[$k] );
494 $active_plugins[$k] = $formatted;
495 } else {
496 $plugins[$k] = $formatted;
497 }
498 }
499
500 return array( 'active_plugins' => $active_plugins, 'inactive_plugins' => $plugins );
501 }
502
503 /**
504 * Get user totals based on user role.
505 *
506 * @return array
507 */
508 public function get_user_counts() {
509 $user_count = array();
510 $user_count_data = count_users();
511 $user_count['total'] = $user_count_data['total_users'];
512
513 // Get user count based on user role
514 foreach ( $user_count_data['avail_roles'] as $role => $count ) {
515 $user_count[ $role ] = $count;
516 }
517
518 return $user_count;
519 }
520
521 /**
522 * Add weekly cron schedule
523 *
524 * @param array $schedules
525 *
526 * @return array
527 */
528 public function add_weekly_schedule( $schedules ) {
529
530 $schedules['weekly'] = array(
531 'interval' => DAY_IN_SECONDS * 7,
532 'display' => 'Once Weekly',
533 );
534
535 return $schedules;
536 }
537
538 /**
539 * Plugin activation hook
540 *
541 * @return void
542 */
543 public function activate_plugin() {
544 $allowed = get_option( $this->client->slug . '_allow_tracking', 'no' );
545
546 // if it wasn't allowed before, do nothing
547 if ( 'yes' !== $allowed ) {
548 return;
549 }
550
551 // re-schedule and delete the last sent time so we could force send again
552 $hook_name = $this->client->slug . '_tracker_send_event';
553 if ( ! wp_next_scheduled( $hook_name ) ) {
554 wp_schedule_event( time(), 'weekly', $hook_name );
555 }
556
557 delete_option( $this->client->slug . '_tracking_last_send' );
558
559 $this->send_tracking_data( true );
560 }
561
562 /**
563 * Clear our options upon deactivation
564 *
565 * @return void
566 */
567 public function deactivation_cleanup() {
568 $this->clear_schedule_event();
569
570 if ( 'theme' == $this->client->type ) {
571 delete_option( $this->client->slug . '_tracking_last_send' );
572 delete_option( $this->client->slug . '_allow_tracking' );
573 }
574
575 delete_option( $this->client->slug . '_tracking_notice' );
576 }
577
578 /**
579 * Hook into action links and modify the deactivate link
580 *
581 * @param array $links
582 *
583 * @return array
584 */
585 public function plugin_action_links( $links ) {
586
587 if ( array_key_exists( 'deactivate', $links ) ) {
588 $links['deactivate'] = str_replace( '<a', '<a class="' . $this->client->slug . '-deactivate-link"', $links['deactivate'] );
589 }
590
591 return $links;
592 }
593
594 private function get_uninstall_reasons() {
595 $reasons = array(
596 array(
597 'id' => 'could-not-understand',
598 'text' => 'I couldn\'t understand how to make it work',
599 'type' => 'textarea',
600 'placeholder' => 'Would you like us to assist you?'
601 ),
602 array(
603 'id' => 'found-better-plugin',
604 'text' => 'I found a better plugin',
605 'type' => 'text',
606 'placeholder' => 'Which plugin?'
607 ),
608 array(
609 'id' => 'not-have-that-feature',
610 'text' => 'The plugin is great, but I need specific feature that you don\'t support',
611 'type' => 'textarea',
612 'placeholder' => 'Could you tell us more about that feature?'
613 ),
614 array(
615 'id' => 'is-not-working',
616 'text' => 'The plugin is not working',
617 'type' => 'textarea',
618 'placeholder' => 'Could you tell us a bit more whats not working?'
619 ),
620 array(
621 'id' => 'looking-for-other',
622 'text' => 'It\'s not what I was looking for',
623 'type' => '',
624 'placeholder' => ''
625 ),
626 array(
627 'id' => 'did-not-work-as-expected',
628 'text' => 'The plugin didn\'t work as expected',
629 'type' => 'textarea',
630 'placeholder' => 'What did you expect?'
631 ),
632 array(
633 'id' => 'other',
634 'text' => 'Other',
635 'type' => 'textarea',
636 'placeholder' => 'Could you tell us a bit more?'
637 ),
638 );
639
640 return $reasons;
641 }
642
643 /**
644 * Plugin deactivation uninstall reason submission
645 *
646 * @return void
647 */
648 public function uninstall_reason_submission() {
649
650 if ( ! isset( $_POST['reason_id'] ) ) {
651 wp_send_json_error();
652 }
653
654 $current_user = wp_get_current_user();
655
656 $data = array(
657 'hash' => $this->client->hash,
658 'reason_id' => sanitize_text_field( $_POST['reason_id'] ),
659 'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( stripslashes( $_REQUEST['reason_info'] ) ) : '',
660 'site' => $this->get_site_name(),
661 'url' => esc_url( home_url() ),
662 'admin_email' => get_option( 'admin_email' ),
663 'user_email' => $current_user->user_email,
664 'first_name' => $current_user->first_name,
665 'last_name' => $current_user->last_name,
666 'server' => $this->get_server_info(),
667 'wp' => $this->get_wp_info(),
668 'ip_address' => $this->get_user_ip_address(),
669 'theme' => get_stylesheet(),
670 'version' => $this->client->project_version,
671 );
672
673 // Add metadata
674 if ( $extra = $this->get_extra_data() ) {
675 $data['extra'] = $extra;
676 }
677
678 $this->client->send_request( $data, 'deactivate' );
679
680 wp_send_json_success();
681 }
682
683 /**
684 * Handle the plugin deactivation feedback
685 *
686 * @return void
687 */
688 public function deactivate_scripts() {
689 global $pagenow;
690
691 if ( 'plugins.php' != $pagenow ) {
692 return;
693 }
694
695 $reasons = $this->get_uninstall_reasons();
696 ?>
697
698 <div class="wd-dr-modal" id="<?php echo $this->client->slug; ?>-wd-dr-modal">
699 <div class="wd-dr-modal-wrap">
700 <div class="wd-dr-modal-header">
701 <h3><?php _e( 'If you have a moment, please let us know why you are deactivating:', $this->client->textdomain, 'weforms' ); ?></h3>
702 </div>
703
704 <div class="wd-dr-modal-body">
705 <ul class="reasons">
706 <?php foreach ($reasons as $reason) { ?>
707 <li data-type="<?php echo esc_attr( $reason['type'] ); ?>" data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>">
708 <label><input type="radio" name="selected-reason" value="<?php echo $reason['id']; ?>"> <?php echo $reason['text']; ?></label>
709 </li>
710 <?php } ?>
711 </ul>
712 <p class="wd-dr-modal-reasons-bottom">We share your data with <a href="https://appsero.com/">Appsero</a> to troubleshoot problems &amp; make product improvements. <a href="https://appsero.com/privacy-policy/">Learn more</a> about how Appsero handles your data.</p>
713 </div>
714
715 <div class="wd-dr-modal-footer">
716 <a href="#" class="dont-bother-me"><?php _e( 'I rather wouldn\'t say', $this->client->textdomain, 'weforms' ); ?></a>
717 <button class="button-secondary"><?php _e( 'Submit & Deactivate', $this->client->textdomain, 'weforms' ); ?></button>
718 <button class="button-primary"><?php _e( 'Cancel', $this->client->textdomain, 'weforms' ); ?></button>
719 </div>
720 </div>
721 </div>
722
723 <style type="text/css">
724 .wd-dr-modal {
725 position: fixed;
726 z-index: 99999;
727 top: 0;
728 right: 0;
729 bottom: 0;
730 left: 0;
731 background: rgba(0,0,0,0.5);
732 display: none;
733 }
734
735 .wd-dr-modal.modal-active {
736 display: block;
737 }
738
739 .wd-dr-modal-wrap {
740 width: 475px;
741 position: relative;
742 margin: 10% auto;
743 background: #fff;
744 }
745
746 .wd-dr-modal-header {
747 border-bottom: 1px solid #eee;
748 padding: 8px 20px;
749 }
750
751 .wd-dr-modal-header h3 {
752 line-height: 150%;
753 margin: 0;
754 }
755
756 .wd-dr-modal-body {
757 padding: 5px 20px 20px 20px;
758 }
759
760 .wd-dr-modal-body .reason-input {
761 margin-top: 5px;
762 margin-left: 20px;
763 }
764 .wd-dr-modal-footer {
765 border-top: 1px solid #eee;
766 padding: 12px 20px;
767 text-align: right;
768 }
769 .wd-dr-modal-reasons-bottom {
770 margin: 15px 0 0 0;
771 }
772 </style>
773
774 <script type="text/javascript">
775 (function($) {
776 $(function() {
777 var modal = $( '#<?php echo $this->client->slug; ?>-wd-dr-modal' );
778 var deactivateLink = '';
779
780 $( '#the-list' ).on('click', 'a.<?php echo $this->client->slug; ?>-deactivate-link', function(e) {
781 e.preventDefault();
782
783 modal.addClass('modal-active');
784 deactivateLink = $(this).attr('href');
785 modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left');
786 });
787
788 modal.on('click', 'button.button-primary', function(e) {
789 e.preventDefault();
790
791 modal.removeClass('modal-active');
792 });
793
794 modal.on('click', 'input[type="radio"]', function () {
795 var parent = $(this).parents('li:first');
796
797 modal.find('.reason-input').remove();
798
799 var inputType = parent.data('type'),
800 inputPlaceholder = parent.data('placeholder'),
801 reasonInputHtml = '<div class="reason-input">' + ( ( 'text' === inputType ) ? '<input type="text" size="40" />' : '<textarea rows="5" cols="45"></textarea>' ) + '</div>';
802
803 if ( inputType !== '' ) {
804 parent.append( $(reasonInputHtml) );
805 parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
806 }
807 });
808
809 modal.on('click', 'button.button-secondary', function(e) {
810 e.preventDefault();
811
812 var button = $(this);
813
814 if ( button.hasClass('disabled') ) {
815 return;
816 }
817
818 var $radio = $( 'input[type="radio"]:checked', modal );
819
820 var $selected_reason = $radio.parents('li:first'),
821 $input = $selected_reason.find('textarea, input[type="text"]');
822
823 $.ajax({
824 url: ajaxurl,
825 type: 'POST',
826 data: {
827 action: '<?php echo $this->client->slug; ?>_submit-uninstall-reason',
828 reason_id: ( 0 === $radio.length ) ? 'none' : $radio.val(),
829 reason_info: ( 0 !== $input.length ) ? $input.val().trim() : ''
830 },
831 beforeSend: function() {
832 button.addClass('disabled');
833 button.text('Processing...');
834 },
835 complete: function() {
836 window.location.href = deactivateLink;
837 }
838 });
839 });
840 });
841 }(jQuery));
842 </script>
843
844 <?php
845 }
846
847 /**
848 * Run after theme deactivated
849 * @param string $new_name
850 * @param object $new_theme
851 * @param object $old_theme
852 * @return void
853 */
854 public function theme_deactivated( $new_name, $new_theme, $old_theme ) {
855 // Make sure this is appsero theme
856 if ( $old_theme->get_template() == $this->client->slug ) {
857 $current_user = wp_get_current_user();
858
859 $data = array(
860 'hash' => $this->client->hash,
861 'reason_id' => 'none',
862 'reason_info' => '',
863 'site' => $this->get_site_name(),
864 'url' => esc_url( home_url() ),
865 'admin_email' => get_option( 'admin_email' ),
866 'user_email' => $current_user->user_email,
867 'first_name' => $current_user->first_name,
868 'last_name' => $current_user->last_name,
869 'server' => $this->get_server_info(),
870 'wp' => $this->get_wp_info(),
871 'ip_address' => $this->get_user_ip_address(),
872 'theme' => get_stylesheet(),
873 'version' => $this->client->project_version,
874 );
875
876 $this->client->send_request( $data, 'deactivate' );
877 }
878 }
879
880 /**
881 * Get user IP Address
882 */
883 private function get_user_ip_address() {
884 $response = wp_remote_get( 'https://icanhazip.com/' );
885
886 if ( is_wp_error( $response ) ) {
887 return '';
888 }
889
890 $ip = trim( wp_remote_retrieve_body( $response ) );
891
892 if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
893 return '';
894 }
895
896 return $ip;
897 }
898
899 /**
900 * Get site name
901 */
902 private function get_site_name() {
903 $site_name = get_bloginfo( 'name' );
904
905 if ( empty( $site_name ) ) {
906 $site_name = get_bloginfo( 'description' );
907 $site_name = wp_trim_words( $site_name, 3, '' );
908 }
909
910 if ( empty( $site_name ) ) {
911 $site_name = get_bloginfo( 'url' );
912 }
913
914 return $site_name;
915 }
916 }
917