PluginProbe
weForms – Easy Drag & Drop Contact Form Builder For WordPress / 1.4.8
weForms – Easy Drag & Drop Contact Form Builder For WordPress v1.4.8
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.4.8, at includes/library/appsero/Insights.php

963 lines 29.8 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 $hide_notice = get_option( $this->client->slug . '_tracking_notice', null );
301
302 if ( 'hide' == $hide_notice ) {
303 return true;
304 }
305
306 return false;
307 }
308
309 /**
310 * Check if the current server is localhost
311 *
312 * @return boolean
313 */
314 private function is_local_server() {
315 return false;
316
317 $is_local = in_array( $_SERVER['REMOTE_ADDR'], array( '127.0.0.1', '::1' ) );
318
319 return apply_filters( 'appsero_is_local', $is_local );
320 }
321
322 /**
323 * Schedule the event weekly
324 *
325 * @return void
326 */
327 private function schedule_event() {
328 $hook_name = $this->client->slug . '_tracker_send_event';
329
330 if ( ! wp_next_scheduled( $hook_name ) ) {
331 wp_schedule_event( time(), 'weekly', $hook_name );
332 }
333 }
334
335 /**
336 * Clear any scheduled hook
337 *
338 * @return void
339 */
340 private function clear_schedule_event() {
341 wp_clear_scheduled_hook( $this->client->slug . '_tracker_send_event' );
342 }
343
344 /**
345 * Display the admin notice to users that have not opted-in or out
346 *
347 * @return void
348 */
349 public function admin_notice() {
350
351 if ( $this->notice_dismissed() ) {
352 return;
353 }
354
355 if ( $this->tracking_allowed() ) {
356 return;
357 }
358
359 if ( ! current_user_can( 'manage_options' ) ) {
360 return;
361 }
362
363 // don't show tracking if a local server
364 if ( ! $this->is_local_server() ) {
365 $optin_url = add_query_arg( $this->client->slug . '_tracker_optin', 'true' );
366 $optout_url = add_query_arg( $this->client->slug . '_tracker_optout', 'true' );
367
368 if ( empty( $this->notice ) ) {
369 $notice = sprintf( __( 'Want to help make <strong>%1$s</strong> even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.', $this->client->textdomain, 'weforms' ), $this->client->name );
370 } else {
371 $notice = $this->notice;
372 }
373
374 $notice .= ' (<a class="' . $this->client->slug . '-insights-data-we-collect" href="#">' . __( 'what we collect', $this->client->textdomain, 'weforms' ) . '</a>)';
375 $notice .= '<p class="description" style="display:none;">' . implode( ', ', $this->data_we_collect() ) . '. No sensitive data is tracked. ';
376 $notice .= 'We are using Appsero to collect your data. <a href="https://appsero.com/privacy-policy/">Learn more</a> about how Appsero collects and handle your data.</p>';
377
378 echo '<div class="updated"><p>';
379 echo $notice;
380 echo '</p><p class="submit">';
381 echo '&nbsp;<a href="' . esc_url( $optin_url ) . '" class="button-primary button-large">' . __( 'Allow', $this->client->textdomain, 'weforms' ) . '</a>';
382 echo '&nbsp;<a href="' . esc_url( $optout_url ) . '" class="button-secondary button-large">' . __( 'No thanks', $this->client->textdomain, 'weforms' ) . '</a>';
383 echo '</p></div>';
384
385 echo "<script type='text/javascript'>jQuery('." . $this->client->slug . "-insights-data-we-collect').on('click', function(e) {
386 e.preventDefault();
387 jQuery(this).parents('.updated').find('p.description').slideToggle('fast');
388 });
389 </script>
390 ";
391 }
392 }
393
394 /**
395 * handle the optin/optout
396 *
397 * @return void
398 */
399 public function handle_optin_optout() {
400
401 if ( isset( $_GET[ $this->client->slug . '_tracker_optin' ] ) && $_GET[ $this->client->slug . '_tracker_optin' ] == 'true' ) {
402 $this->optin();
403
404 wp_redirect( remove_query_arg( $this->client->slug . '_tracker_optin' ) );
405 exit;
406 }
407
408 if ( isset( $_GET[ $this->client->slug . '_tracker_optout' ] ) && $_GET[ $this->client->slug . '_tracker_optout' ] == 'true' ) {
409 $this->optout();
410
411 wp_redirect( remove_query_arg( $this->client->slug . '_tracker_optout' ) );
412 exit;
413 }
414 }
415
416 /**
417 * Tracking optin
418 *
419 * @return void
420 */
421 public function optin() {
422 update_option( $this->client->slug . '_allow_tracking', 'yes' );
423 update_option( $this->client->slug . '_tracking_notice', 'hide' );
424
425 $this->clear_schedule_event();
426 $this->schedule_event();
427 $this->send_tracking_data();
428 }
429
430 /**
431 * Optout from tracking
432 *
433 * @return void
434 */
435 public function optout() {
436 update_option( $this->client->slug . '_allow_tracking', 'no' );
437 update_option( $this->client->slug . '_tracking_notice', 'hide' );
438
439 $this->clear_schedule_event();
440 }
441
442 /**
443 * Get the number of post counts
444 *
445 * @param string $post_type
446 *
447 * @return integer
448 */
449 public function get_post_count( $post_type ) {
450 global $wpdb;
451
452 return (int) $wpdb->get_var( "SELECT count(ID) FROM $wpdb->posts WHERE post_type = '$post_type' and post_status = 'publish'");
453 }
454
455 /**
456 * Get server related info.
457 *
458 * @return array
459 */
460 private static function get_server_info() {
461 global $wpdb;
462
463 $server_data = array();
464
465 if ( isset( $_SERVER['SERVER_SOFTWARE'] ) && ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) {
466 $server_data['software'] = $_SERVER['SERVER_SOFTWARE'];
467 }
468
469 if ( function_exists( 'phpversion' ) ) {
470 $server_data['php_version'] = phpversion();
471 }
472
473 $server_data['mysql_version'] = $wpdb->db_version();
474
475 $server_data['php_max_upload_size'] = size_format( wp_max_upload_size() );
476 $server_data['php_default_timezone'] = date_default_timezone_get();
477 $server_data['php_soap'] = class_exists( 'SoapClient' ) ? 'Yes' : 'No';
478 $server_data['php_fsockopen'] = function_exists( 'fsockopen' ) ? 'Yes' : 'No';
479 $server_data['php_curl'] = function_exists( 'curl_init' ) ? 'Yes' : 'No';
480
481 return $server_data;
482 }
483
484 /**
485 * Get WordPress related data.
486 *
487 * @return array
488 */
489 private function get_wp_info() {
490 $wp_data = array();
491
492 $wp_data['memory_limit'] = WP_MEMORY_LIMIT;
493 $wp_data['debug_mode'] = ( defined('WP_DEBUG') && WP_DEBUG ) ? 'Yes' : 'No';
494 $wp_data['locale'] = get_locale();
495 $wp_data['version'] = get_bloginfo( 'version' );
496 $wp_data['multisite'] = is_multisite() ? 'Yes' : 'No';
497
498 return $wp_data;
499 }
500
501 /**
502 * Get the list of active and inactive plugins
503 *
504 * @return array
505 */
506 private function get_all_plugins() {
507 // Ensure get_plugins function is loaded
508 if ( ! function_exists( 'get_plugins' ) ) {
509 include ABSPATH . '/wp-admin/includes/plugin.php';
510 }
511
512 $plugins = get_plugins();
513 $active_plugins_keys = get_option( 'active_plugins', array() );
514 $active_plugins = array();
515
516 foreach ( $plugins as $k => $v ) {
517 // Take care of formatting the data how we want it.
518 $formatted = array();
519 $formatted['name'] = strip_tags( $v['Name'] );
520
521 if ( isset( $v['Version'] ) ) {
522 $formatted['version'] = strip_tags( $v['Version'] );
523 }
524
525 if ( isset( $v['Author'] ) ) {
526 $formatted['author'] = strip_tags( $v['Author'] );
527 }
528
529 if ( isset( $v['Network'] ) ) {
530 $formatted['network'] = strip_tags( $v['Network'] );
531 }
532
533 if ( isset( $v['PluginURI'] ) ) {
534 $formatted['plugin_uri'] = strip_tags( $v['PluginURI'] );
535 }
536
537 if ( in_array( $k, $active_plugins_keys ) ) {
538 // Remove active plugins from list so we can show active and inactive separately
539 unset( $plugins[$k] );
540 $active_plugins[$k] = $formatted;
541 } else {
542 $plugins[$k] = $formatted;
543 }
544 }
545
546 return array( 'active_plugins' => $active_plugins, 'inactive_plugins' => $plugins );
547 }
548
549 /**
550 * Get user totals based on user role.
551 *
552 * @return array
553 */
554 public function get_user_counts() {
555 $user_count = array();
556 $user_count_data = count_users();
557 $user_count['total'] = $user_count_data['total_users'];
558
559 // Get user count based on user role
560 foreach ( $user_count_data['avail_roles'] as $role => $count ) {
561 $user_count[ $role ] = $count;
562 }
563
564 return $user_count;
565 }
566
567 /**
568 * Add weekly cron schedule
569 *
570 * @param array $schedules
571 *
572 * @return array
573 */
574 public function add_weekly_schedule( $schedules ) {
575
576 $schedules['weekly'] = array(
577 'interval' => DAY_IN_SECONDS * 7,
578 'display' => 'Once Weekly',
579 );
580
581 return $schedules;
582 }
583
584 /**
585 * Plugin activation hook
586 *
587 * @return void
588 */
589 public function activate_plugin() {
590 $allowed = get_option( $this->client->slug . '_allow_tracking', 'no' );
591
592 // if it wasn't allowed before, do nothing
593 if ( 'yes' !== $allowed ) {
594 return;
595 }
596
597 // re-schedule and delete the last sent time so we could force send again
598 $hook_name = $this->client->slug . '_tracker_send_event';
599 if ( ! wp_next_scheduled( $hook_name ) ) {
600 wp_schedule_event( time(), 'weekly', $hook_name );
601 }
602
603 delete_option( $this->client->slug . '_tracking_last_send' );
604
605 $this->send_tracking_data( true );
606 }
607
608 /**
609 * Clear our options upon deactivation
610 *
611 * @return void
612 */
613 public function deactivation_cleanup() {
614 $this->clear_schedule_event();
615
616 if ( 'theme' == $this->client->type ) {
617 delete_option( $this->client->slug . '_tracking_last_send' );
618 delete_option( $this->client->slug . '_allow_tracking' );
619 }
620
621 delete_option( $this->client->slug . '_tracking_notice' );
622 }
623
624 /**
625 * Hook into action links and modify the deactivate link
626 *
627 * @param array $links
628 *
629 * @return array
630 */
631 public function plugin_action_links( $links ) {
632
633 if ( array_key_exists( 'deactivate', $links ) ) {
634 $links['deactivate'] = str_replace( '<a', '<a class="' . $this->client->slug . '-deactivate-link"', $links['deactivate'] );
635 }
636
637 return $links;
638 }
639
640 private function get_uninstall_reasons() {
641 $reasons = array(
642 array(
643 'id' => 'could-not-understand',
644 'text' => 'I couldn\'t understand how to make it work',
645 'type' => 'textarea',
646 'placeholder' => 'Would you like us to assist you?'
647 ),
648 array(
649 'id' => 'found-better-plugin',
650 'text' => 'I found a better plugin',
651 'type' => 'text',
652 'placeholder' => 'Which plugin?'
653 ),
654 array(
655 'id' => 'not-have-that-feature',
656 'text' => 'The plugin is great, but I need specific feature that you don\'t support',
657 'type' => 'textarea',
658 'placeholder' => 'Could you tell us more about that feature?'
659 ),
660 array(
661 'id' => 'is-not-working',
662 'text' => 'The plugin is not working',
663 'type' => 'textarea',
664 'placeholder' => 'Could you tell us a bit more whats not working?'
665 ),
666 array(
667 'id' => 'looking-for-other',
668 'text' => 'It\'s not what I was looking for',
669 'type' => '',
670 'placeholder' => ''
671 ),
672 array(
673 'id' => 'did-not-work-as-expected',
674 'text' => 'The plugin didn\'t work as expected',
675 'type' => 'textarea',
676 'placeholder' => 'What did you expect?'
677 ),
678 array(
679 'id' => 'other',
680 'text' => 'Other',
681 'type' => 'textarea',
682 'placeholder' => 'Could you tell us a bit more?'
683 ),
684 );
685
686 return $reasons;
687 }
688
689 /**
690 * Plugin deactivation uninstall reason submission
691 *
692 * @return void
693 */
694 public function uninstall_reason_submission() {
695
696 if ( ! isset( $_POST['reason_id'] ) ) {
697 wp_send_json_error();
698 }
699
700 $current_user = wp_get_current_user();
701
702 $data = array(
703 'hash' => $this->client->hash,
704 'reason_id' => sanitize_text_field( $_POST['reason_id'] ),
705 'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( stripslashes( $_REQUEST['reason_info'] ) ) : '',
706 'site' => $this->get_site_name(),
707 'url' => esc_url( home_url() ),
708 'admin_email' => get_option( 'admin_email' ),
709 'user_email' => $current_user->user_email,
710 'first_name' => $current_user->first_name,
711 'last_name' => $current_user->last_name,
712 'server' => $this->get_server_info(),
713 'wp' => $this->get_wp_info(),
714 'ip_address' => $this->get_user_ip_address(),
715 'theme' => get_stylesheet(),
716 'version' => $this->client->project_version,
717 );
718
719 // Add metadata
720 if ( $extra = $this->get_extra_data() ) {
721 $data['extra'] = $extra;
722 }
723
724 $this->client->send_request( $data, 'deactivate' );
725
726 wp_send_json_success();
727 }
728
729 /**
730 * Handle the plugin deactivation feedback
731 *
732 * @return void
733 */
734 public function deactivate_scripts() {
735 global $pagenow;
736
737 if ( 'plugins.php' != $pagenow ) {
738 return;
739 }
740
741 $reasons = $this->get_uninstall_reasons();
742 ?>
743
744 <div class="wd-dr-modal" id="<?php echo $this->client->slug; ?>-wd-dr-modal">
745 <div class="wd-dr-modal-wrap">
746 <div class="wd-dr-modal-header">
747 <h3><?php _e( 'If you have a moment, please let us know why you are deactivating:', $this->client->textdomain, 'weforms' ); ?></h3>
748 </div>
749
750 <div class="wd-dr-modal-body">
751 <ul class="reasons">
752 <?php foreach ($reasons as $reason) { ?>
753 <li data-type="<?php echo esc_attr( $reason['type'] ); ?>" data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>">
754 <label><input type="radio" name="selected-reason" value="<?php echo $reason['id']; ?>"> <?php echo $reason['text']; ?></label>
755 </li>
756 <?php } ?>
757 </ul>
758 <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>
759 </div>
760
761 <div class="wd-dr-modal-footer">
762 <a href="#" class="dont-bother-me"><?php _e( 'I rather wouldn\'t say', $this->client->textdomain, 'weforms' ); ?></a>
763 <button class="button-secondary"><?php _e( 'Submit & Deactivate', $this->client->textdomain, 'weforms' ); ?></button>
764 <button class="button-primary"><?php _e( 'Cancel', $this->client->textdomain, 'weforms' ); ?></button>
765 </div>
766 </div>
767 </div>
768
769 <style type="text/css">
770 .wd-dr-modal {
771 position: fixed;
772 z-index: 99999;
773 top: 0;
774 right: 0;
775 bottom: 0;
776 left: 0;
777 background: rgba(0,0,0,0.5);
778 display: none;
779 }
780
781 .wd-dr-modal.modal-active {
782 display: block;
783 }
784
785 .wd-dr-modal-wrap {
786 width: 475px;
787 position: relative;
788 margin: 10% auto;
789 background: #fff;
790 }
791
792 .wd-dr-modal-header {
793 border-bottom: 1px solid #eee;
794 padding: 8px 20px;
795 }
796
797 .wd-dr-modal-header h3 {
798 line-height: 150%;
799 margin: 0;
800 }
801
802 .wd-dr-modal-body {
803 padding: 5px 20px 20px 20px;
804 }
805
806 .wd-dr-modal-body .reason-input {
807 margin-top: 5px;
808 margin-left: 20px;
809 }
810 .wd-dr-modal-footer {
811 border-top: 1px solid #eee;
812 padding: 12px 20px;
813 text-align: right;
814 }
815 .wd-dr-modal-reasons-bottom {
816 margin: 15px 0 0 0;
817 }
818 </style>
819
820 <script type="text/javascript">
821 (function($) {
822 $(function() {
823 var modal = $( '#<?php echo $this->client->slug; ?>-wd-dr-modal' );
824 var deactivateLink = '';
825
826 $( '#the-list' ).on('click', 'a.<?php echo $this->client->slug; ?>-deactivate-link', function(e) {
827 e.preventDefault();
828
829 modal.addClass('modal-active');
830 deactivateLink = $(this).attr('href');
831 modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left');
832 });
833
834 modal.on('click', 'button.button-primary', function(e) {
835 e.preventDefault();
836
837 modal.removeClass('modal-active');
838 });
839
840 modal.on('click', 'input[type="radio"]', function () {
841 var parent = $(this).parents('li:first');
842
843 modal.find('.reason-input').remove();
844
845 var inputType = parent.data('type'),
846 inputPlaceholder = parent.data('placeholder'),
847 reasonInputHtml = '<div class="reason-input">' + ( ( 'text' === inputType ) ? '<input type="text" size="40" />' : '<textarea rows="5" cols="45"></textarea>' ) + '</div>';
848
849 if ( inputType !== '' ) {
850 parent.append( $(reasonInputHtml) );
851 parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus();
852 }
853 });
854
855 modal.on('click', 'button.button-secondary', function(e) {
856 e.preventDefault();
857
858 var button = $(this);
859
860 if ( button.hasClass('disabled') ) {
861 return;
862 }
863
864 var $radio = $( 'input[type="radio"]:checked', modal );
865
866 var $selected_reason = $radio.parents('li:first'),
867 $input = $selected_reason.find('textarea, input[type="text"]');
868
869 $.ajax({
870 url: ajaxurl,
871 type: 'POST',
872 data: {
873 action: '<?php echo $this->client->slug; ?>_submit-uninstall-reason',
874 reason_id: ( 0 === $radio.length ) ? 'none' : $radio.val(),
875 reason_info: ( 0 !== $input.length ) ? $input.val().trim() : ''
876 },
877 beforeSend: function() {
878 button.addClass('disabled');
879 button.text('Processing...');
880 },
881 complete: function() {
882 window.location.href = deactivateLink;
883 }
884 });
885 });
886 });
887 }(jQuery));
888 </script>
889
890 <?php
891 }
892
893 /**
894 * Run after theme deactivated
895 * @param string $new_name
896 * @param object $new_theme
897 * @param object $old_theme
898 * @return void
899 */
900 public function theme_deactivated( $new_name, $new_theme, $old_theme ) {
901 // Make sure this is appsero theme
902 if ( $old_theme->get_template() == $this->client->slug ) {
903 $current_user = wp_get_current_user();
904
905 $data = array(
906 'hash' => $this->client->hash,
907 'reason_id' => 'none',
908 'reason_info' => '',
909 'site' => $this->get_site_name(),
910 'url' => esc_url( home_url() ),
911 'admin_email' => get_option( 'admin_email' ),
912 'user_email' => $current_user->user_email,
913 'first_name' => $current_user->first_name,
914 'last_name' => $current_user->last_name,
915 'server' => $this->get_server_info(),
916 'wp' => $this->get_wp_info(),
917 'ip_address' => $this->get_user_ip_address(),
918 'theme' => get_stylesheet(),
919 'version' => $this->client->project_version,
920 );
921
922 $this->client->send_request( $data, 'deactivate' );
923 }
924 }
925
926 /**
927 * Get user IP Address
928 */
929 private function get_user_ip_address() {
930 $response = wp_remote_get( 'https://icanhazip.com/' );
931
932 if ( is_wp_error( $response ) ) {
933 return '';
934 }
935
936 $ip = trim( wp_remote_retrieve_body( $response ) );
937
938 if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) {
939 return '';
940 }
941
942 return $ip;
943 }
944
945 /**
946 * Get site name
947 */
948 private function get_site_name() {
949 $site_name = get_bloginfo( 'name' );
950
951 if ( empty( $site_name ) ) {
952 $site_name = get_bloginfo( 'description' );
953 $site_name = wp_trim_words( $site_name, 3, '' );
954 }
955
956 if ( empty( $site_name ) ) {
957 $site_name = get_bloginfo( 'url' );
958 }
959
960 return $site_name;
961 }
962 }
963