PluginProbe
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services / 8.5.4
WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services v8.5.4
8.7.6 8.7.5 8.7.4 8.7.3 8.7.2 8.7.1 8.7.0 8.6.9 8.6.8 8.6.7 8.6.6 8.6.5 8.6.4 8.6.2 8.6.1 8.6.0 8.5.9 8.5.8 8.5.7 8.5.6 8.5.5 8.5.4 8.5.3 8.5.2 8.5.0 All 532 releases
chatbot / class-plugin-deactivate-feedback.php

class-plugin-deactivate-feedback.php in WPBot – AI ChatBot for Live Support, Lead Generation, WordPress Automation, AI Services 8.5.4, at class-plugin-deactivate-feedback.php

416 lines 13.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Exit if accessed directly
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 if( ! class_exists( 'Qcld_Wp_Usage_Feedback') ) {
9
10 class Qcld_Wp_Usage_Feedback {
11
12 private $wpbot_version = '1.0.0';
13 private $home_url = '';
14 private $plugin_file = '';
15 private $plugin_name = '';
16 private $options = array();
17 private $require_optin = true;
18 private $include_goodbye_form = true;
19
20
21 /**
22 * Class constructor
23 *
24 * @param $_home_url The URL to the site we're sending data to
25 * @param $_plugin_file The file path for this plugin
26 * @param $_options Plugin options to track
27 * @param $_require_optin Whether user opt-in is required (always required on WordPress.org)
28 * @param $_include_goodbye_form Whether to include a form when the user deactivates
29 * @param $_marketing Marketing method:
30 * 0: Don't collect email addresses
31 * 1: Request permission same time as tracking opt-in
32 * 2: Request permission after opt-in
33 */
34 public function __construct(
35 $_plugin_file,
36 $_home_url,
37
38 $_require_optin=true,
39 $_include_goodbye_form=true) {
40
41 $this->plugin_file = $_plugin_file;
42 $this->home_url = 'plugins@quantumcloud.com';
43 $this->plugin_name = basename( $this->plugin_file, '.php' );
44
45 $this->require_optin = $_require_optin;
46 $this->include_goodbye_form = $_include_goodbye_form;
47
48
49 // Deactivation hook
50 register_deactivation_hook( $this->plugin_file, array( $this, 'deactivate_this_plugin' ) );
51
52 // Get it going
53 $this->init();
54
55 }
56
57 public function init() {
58
59 // Deactivation
60 add_filter( 'plugin_action_links_' . plugin_basename( $this->plugin_file ), array( $this, 'filter_action_links' ) );
61 add_action( 'admin_footer-plugins.php', array( $this, 'goodbye_ajax' ) );
62 add_action( 'wp_ajax_qcld_goodbye_form', array( $this, 'qcld_goodbye_form_callback' ) );
63
64
65 }
66
67 // In theme's functions.php or plug-in code:
68
69 function set_content_type(){
70 return "text/html";
71 }
72
73
74 /**
75 * Send the data to the home site
76 *
77 * @since 1.0.0
78 */
79 public function send_data( $body ) {
80 $message = '';
81 foreach($body as $key=>$value){
82
83 if($key=='active_plugins'){
84 $message .='<p> <b>'.$key.'</b>: '.(implode(', ',$value)).' </p>';
85 }
86 elseif($key=='inactive_plugins'){
87 $message .='<p> <b>'.$key.'</b>: '.(implode(', ',$value)).' </p>';
88 }else{
89 $message .='<p> <b>'.$key.'</b>: '.$value.' </p>';
90 }
91
92 }
93
94 $title = 'Plugin Deactivation Notice';
95 $headers = array('From: Anonymous <mailer@just-a-fake-from-address.com>');
96
97 add_filter( 'wp_mail_content_type', array($this, 'set_content_type') );
98 $email = wp_mail($this->home_url, $title, $message, $headers);
99 remove_filter('wp_mail_content_type', array($this, 'set_content_type'));
100
101 return $email;
102
103 }
104
105 /**
106 * Here we collect most of the data
107 *
108 * @since 1.0.0
109 */
110 public function get_data() {
111
112 // Use this to pass error messages back if necessary
113 $body['message'] = '';
114
115 // Use this array to send data back
116 $body = array();
117
118
119
120 /**
121 * Get our plugin data
122 * Currently we grab plugin name and version
123 * Or, return a message if the plugin data is not available
124 * @since 1.0.0
125 */
126 $plugin = $this->plugin_data();
127 if( empty( $plugin ) ) {
128 // We can't find the plugin data
129 // Send a message back to our home site
130 $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.', 'chatbot' );
131 $body['status'] = 'Data not found'; // Never translated
132 } else {
133 if( isset( $plugin['Name'] ) ) {
134 $body['plugin'] = sanitize_text_field( $plugin['Name'] );
135 }
136 if( isset( $plugin['Version'] ) ) {
137 $body['version'] = sanitize_text_field( $plugin['Version'] );
138 }
139
140 }
141
142 // Return the data
143 return $body;
144
145 }
146
147 /**
148 * Return plugin data
149 * @since 1.0.0
150 */
151 public function plugin_data() {
152 // Being cautious here
153 if( ! function_exists( 'get_plugin_data' ) ) {
154 include ABSPATH . '/wp-admin/includes/plugin.php';
155 }
156 // Retrieve current plugin information
157 $plugin = get_plugin_data( $this->plugin_file );
158 return $plugin;
159 }
160
161 /**
162 * Deactivating plugin
163 * @since 1.0.0
164 */
165 public function deactivate_this_plugin() {
166
167 $body = $this->get_data();
168 $body['status'] = 'Deactivated'; // Never translated
169 $body['deactivated_date'] = date('Y-m-d');
170
171 // Add deactivation form data
172 if( false !== get_option( 'wpbot_deactivation_reason_' . $this->plugin_name ) ) {
173 $body['deactivation_reason'] = get_option( 'wpbot_deactivation_reason_' . $this->plugin_name );
174 delete_option('wpbot_deactivation_reason_' . $this->plugin_name);
175 }
176 if( false !== get_option( 'wpbot_deactivation_details_' . $this->plugin_name ) ) {
177 $body['deactivation_details'] = get_option( 'wpbot_deactivation_details_' . $this->plugin_name );
178 delete_option('wpbot_deactivation_details_' . $this->plugin_name);
179 }
180
181 if(isset($body['deactivation_reason']) or isset($body['deactivation_details']))
182 $this->send_data( $body );
183
184
185 }
186
187 /**
188 * Filter the deactivation link to allow us to present a form when the user deactivates the plugin
189 * @since 1.0.0
190 */
191 public function filter_action_links( $links ) {
192
193 if( isset( $links['deactivate'] ) && $this->include_goodbye_form ) {
194 $deactivation_link = $links['deactivate'];
195 // Insert an onClick action to allow form before deactivating
196 $deactivation_link = str_replace( '<a ', '<div class="wpb-goodbye-form-wrapper"><span class="wpb-goodbye-form" id="wpb-goodbye-form-' . esc_attr( $this->plugin_name ) . '"></span></div><a onclick="javascript:event.preventDefault();" id="wpb-goodbye-link-' . esc_attr( $this->plugin_name ) . '" ', $deactivation_link );
197 $links['deactivate'] = $deactivation_link;
198 }
199 return $links;
200 }
201
202 /*
203 * Form text strings
204 * These are non-filterable and used as fallback in case filtered strings aren't set correctly
205 * @since 1.0.0
206 */
207 public function form_default_text() {
208 $form = array();
209 $form['heading'] = __( 'Sorry to see you go', 'chatbot' );
210 $form['body'] = '';
211 $form['options'] = array(
212 __( 'Found a Bug', 'chatbot' ),
213 __( 'Need More Features', 'chatbot' ),
214 __( 'Deactivating Temporarily', 'chatbot' ),
215 __( 'Upgrading to Pro', 'chatbot' ),
216
217 );
218 $form['email'] = __( 'Please provide email so we can contact with bug fixes', 'chatbot' );
219 $form['details'] = __( 'Please provide some details so we can improve the plugin', 'chatbot' );
220 return $form;
221 }
222
223 /**
224 * Form text strings
225 * These can be filtered
226 * The filter hook must be unique to the plugin
227 * @since 1.0.0
228 */
229 public function form_filterable_text() {
230 $form = $this->form_default_text();
231 return apply_filters( 'wpbot_form_text_' . esc_attr( $this->plugin_name ), $form );
232 }
233
234 /**
235 * Form text strings
236 * These can be filtered
237 * @since 1.0.0
238 */
239 public function goodbye_ajax() {
240 // Get our strings for the form
241 $form = $this->form_filterable_text();
242 if( ! isset( $form['heading'] ) || ! isset( $form['body'] ) || ! isset( $form['options'] ) || ! is_array( $form['options'] ) || ! isset( $form['details'] ) ) {
243 // If the form hasn't been filtered correctly, we revert to the default form
244 $form = $this->form_default_text();
245 }
246 // Build the HTML to go in the form
247 $html = '<div class="wpb-goodbye-form-head"><strong>' . esc_html( $form['heading'] ) . '</strong></div>';
248 $html .= '<div class="wpb-goodbye-form-body"><p>' . esc_html( $form['body'] ) . '</p>';
249 if( is_array( $form['options'] ) ) {
250 $html .= '<div class="wpb-goodbye-options"><p>';
251 /*
252 foreach( $form['options'] as $option ) {
253 $html .= '<input type="radio" name="wpb-goodbye-options" id="' . str_replace( " ", "", esc_attr( $option ) ) . '" value="' . esc_attr( $option ) . '"> <label for="' . str_replace( " ", "", esc_attr( $option ) ) . '">' . esc_attr( $option ) . '</label><br>';
254 }
255 */
256 $html .= '</p><div id="wpb_additional_content" style=""><label for="wpb-goodbye-reasons">' . esc_html( $form['email'] ) .'</label><br><input type="email" name="wpb-goodbye-email" id="wpb-goodbye-email" value="'.get_option('admin_email').'" /> (Optional)';
257
258 $html .= '<br><label for="wpb-goodbye-reasons">' . esc_html( $form['details'] ) .'</label><textarea name="wpb-goodbye-reasons" id="wpb-goodbye-reasons" rows="2" style="width:100%"></textarea><div id="wpbot_deactivation_error"></div></div>';
259
260 $html .= '</div><!-- .wpb-goodbye-options -->';
261 }
262 $html .= '</div><!-- .wpb-goodbye-form-body -->';
263 $html .= '<p class="deactivating-spinner"><span class="spinner"></span> ' . __( 'Submitting form', 'chatbot' ) . '</p>';
264
265 ?>
266 <div class="wpb-goodbye-form-bg"></div>
267 <style type="text/css">
268 .wpb-form-active .wpb-goodbye-form-bg {
269 background: rgba( 0, 0, 0, .5 );
270 position: fixed;
271 top: 0;
272 left: 0;
273 width: 100%;
274 height: 100%;
275 }
276 .wpb-goodbye-form-wrapper {
277 position: relative;
278 z-index: 999;
279 display: none;
280 }
281 .wpb-form-active .wpb-goodbye-form-wrapper {
282 display: block;
283 }
284 .wpb-goodbye-form {
285 display: none;
286 }
287 .wpb-form-active .wpb-goodbye-form {
288 position: fixed;
289 max-width: 400px;
290 background: #fff;
291 white-space: normal;
292 z-index: 99;
293 top: 50%;
294 left: 50%;
295 transform: translate(-50%, -50%);
296 border-radius: 5px;
297 }
298 .wpb-goodbye-form-head {
299 background: #7a00aa;
300 color: #fff;
301 padding: 8px 18px;
302 text-align: center;
303 border-radius: 5px 5px 0px 0px;
304 }
305 .wpb-goodbye-form-body {
306 padding: 8px 18px;
307 color: #444;
308 }
309 .deactivating-spinner {
310 display: none;
311 }
312 .deactivating-spinner .spinner {
313 float: none;
314 margin: 4px 4px 0 18px;
315 vertical-align: bottom;
316 visibility: visible;
317 }
318 .wpb-goodbye-form-footer {
319 padding: 8px 18px;
320 min-height: 40px;
321 }
322 #wpbot_deactivation_error{color:red}
323 .wpbot_submit_deactivate{float:right}
324 .wpbot_just_deactivate{float: left;
325 font-size: 12px;
326 }
327 </style>
328 <script>
329 jQuery(document).ready(function($){
330 $('input[type=radio]').on('change', function() {
331 if($(this).val()=='Deactivating Temporarily' || $(this).val()=='Upgrading to Pro'){
332 $('#wpb_additional_content').hide();
333 }else{
334 $('#wpb_additional_content').show();
335 }
336
337 });
338
339 $("#wpb-goodbye-link-<?php echo esc_attr( $this->plugin_name ); ?>").on("click",function(){
340 // We'll send the user to this deactivation link when they've completed or dismissed the form
341 var url = document.getElementById("wpb-goodbye-link-<?php echo esc_attr( $this->plugin_name ); ?>");
342 $('body').toggleClass('wpb-form-active');
343 $("#wpb-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?>").fadeIn();
344 $("#wpb-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?>").html( '<?php echo wp_kses_post( $html ); ?>' + '<div class="wpb-goodbye-form-footer"><p><a class="wpbot_just_deactivate" href="'+url+'">Just Deactivate</a> <a id="wpb-submit-form" class="button primary wpbot_submit_deactivate" href="#">Submit and Deactivate</a></p></div>');
345 $('#wpb-goodbye-reasons').focus();
346 $('#wpb-submit-form').on('click', function(e){
347
348
349 e.preventDefault();
350
351 if($('#wpb-goodbye-reasons').val()==''){
352 jQuery('#wpbot_deactivation_error').html('Please provide some details to improve the plugin for you!');
353 $('#wpb-goodbye-reasons').focus();
354 return;
355 }
356
357 // As soon as we click, the body of the form should disappear
358 $("#wpb-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?> .wpb-goodbye-form-body").fadeOut();
359 $("#wpb-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?> .wpb-goodbye-form-footer").fadeOut();
360 // Fade in spinner
361 $("#wpb-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?> .deactivating-spinner").fadeIn();
362
363 var values = new Array();
364 $.each($("input[name='wpb-goodbye-options[]']:checked"), function(){
365 values.push($(this).val());
366 });
367 var email = $('#wpb-goodbye-email').val();
368 var details = $('#wpb-goodbye-reasons').val();
369 var data = {
370 'action': 'qcld_goodbye_form',
371 'values': values,
372 'details': details,
373 'email': email,
374 'security': "<?php echo sanitize_key( wp_create_nonce( 'wpbot_goodbye_form' ) ); ?>",
375 'dataType': "json"
376 }
377
378 $.post(
379 ajaxurl,
380 data,
381 function(response){
382 // Redirect to original deactivation URL
383 window.location.href = url;
384 }
385 );
386 });
387 // If we click outside the form, the form will close
388 $('.wpb-goodbye-form-bg').on('click',function(){
389 $("#wpb-goodbye-form-<?php echo esc_attr( $this->plugin_name ); ?>").fadeOut();
390 $('body').removeClass('wpb-form-active');
391 });
392 });
393 });
394 </script>
395 <?php }
396
397 /**
398 * AJAX callback when the form is submitted
399 * @since 1.0.0
400 */
401 public function qcld_goodbye_form_callback() {
402 check_ajax_referer( 'wpbot_goodbye_form', 'security' );
403
404 if( isset( $_POST['details'] ) ) {
405 $details = sanitize_text_field(wp_unslash($_POST['details']));
406 update_option( 'wpbot_deactivation_details_' . $this->plugin_name, $details );
407 }
408
409 echo 'success';
410 wp_die();
411 }
412
413 }
414
415 }
416