PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents / 3.6.7
EmbedPress – PDF Embedder, 3D PDF FlipBook, Google Reviews, YouTube Videos, Upload & Embed PDF documents v3.6.7
4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / Includes / Classes / EmbedPress_Plugin_Usage_Tracker.php
embedpress / EmbedPress / Includes / Classes Last commit date
Elementor_Enhancer.php 3 years ago EmbedPress_Core_Installer.php 6 years ago EmbedPress_Notice.php 4 years ago EmbedPress_Plugin_Usage_Tracker.php 3 years ago Feature_Enhancer.php 3 years ago Helper.php 3 years ago
EmbedPress_Plugin_Usage_Tracker.php
924 lines
1 <?php
2 /**
3 * EmbedPress_Plugin_Usage_Tracker
4 * This class is responsible for data sending to insights.
5 * @version 3.0.0
6 */
7 namespace EmbedPress\Includes\Classes;
8
9 use WP_Error;
10 /**
11 * Exit if accessed directly
12 */
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit;
15 }
16 /**
17 * Main SDK for EmbedPress_Plugin_Usage_Tracker.
18 */
19 if( ! class_exists('EmbedPress_Plugin_Usage_Tracker') ) :
20 class EmbedPress_Plugin_Usage_Tracker {
21 /**
22 * WP Insights Version
23 */
24 const WPINS_VERSION = '3.0.2';
25 /**
26 * API URL
27 */
28 const API_URL = 'https://send.wpinsight.com/process-plugin-data';
29 /**
30 * Installed Plugin File
31 *
32 * @var string
33 */
34 private $plugin_file = null;
35 /**
36 * Installed Plugin Name
37 *
38 * @var string
39 */
40 private $plugin_name = null;
41 /**
42 * How often the event should subsequently
43 * @var string
44 */
45 public $recurrence = 'daily';
46 private $event_hook = null;
47 /**
48 * Instace of EmbedPress_Plugin_Usage_Tracker
49 * @var EmbedPress_Plugin_Usage_Tracker
50 */
51 private static $_instance = null;
52 /**
53 * Get Instance of EmbedPress_Plugin_Usage_Tracker
54 * @return EmbedPress_Plugin_Usage_Tracker
55 */
56 public static function get_instance( $plugin_file, $args = [] ){
57 if( is_null( static::$_instance ) ) {
58 static::$_instance = new static( $plugin_file, $args );
59 }
60 return static::$_instance;
61 }
62 /**
63 * Automatically Invoked when initialized.
64 *
65 * @param array $args
66 */
67 public function __construct( $plugin_file, $args = [] ){
68 $this->plugin_file = $plugin_file;
69 $this->plugin_name = basename( $this->plugin_file, '.php' );
70 $this->disabled_wp_cron = defined('DISABLE_WP_CRON') && DISABLE_WP_CRON == true;
71 $this->enable_self_cron = $this->disabled_wp_cron == true ? true : false;
72
73 $this->event_hook = 'put_do_weekly_action';
74
75 $this->require_optin = isset( $args['opt_in'] ) ? $args['opt_in'] : true;
76 $this->include_goodbye_form = isset( $args['goodbye_form'] ) ? $args['goodbye_form'] : true;
77 $this->marketing = isset( $args['email_marketing'] ) ? $args['email_marketing'] : true;
78 $this->options = isset( $args['options'] ) ? $args['options'] : [];
79 $this->item_id = isset( $args['item_id'] ) ? $args['item_id'] : false;
80 /**
81 * Activation Hook
82 */
83 register_activation_hook( $this->plugin_file, array( $this, 'activate_this_plugin' ) );
84 /**
85 * Deactivation Hook
86 */
87 register_deactivation_hook( $this->plugin_file, array( $this, 'deactivate_this_plugin' ) );
88 }
89 /**
90 * When user agreed to opt-in tracking schedule is enabled.
91 * @since 3.0.0
92 */
93 public function schedule_tracking() {
94 if( $this->disabled_wp_cron ) {
95 return;
96 }
97 if ( ! wp_next_scheduled( $this->event_hook ) ) {
98 wp_schedule_event( time(), $this->recurrence, $this->event_hook );
99 }
100 }
101 /**
102 * Add the schedule event if the plugin is tracked.
103 *
104 * @return void
105 */
106 public function activate_this_plugin(){
107 $allow_tracking = $this->is_tracking_allowed();
108 if( ! $allow_tracking ) {
109 return;
110 }
111 $this->schedule_tracking();
112 }
113 /**
114 * Remove the schedule event when plugin is deactivated and send the deactivated reason to inishghts if user submitted.
115 * @since 3.0.0
116 */
117 public function deactivate_this_plugin() {
118 /**
119 * Check tracking is allowed or not.
120 */
121 $allow_tracking = $this->is_tracking_allowed();
122 if( ! $allow_tracking ) {
123 return;
124 }
125 $body = $this->get_data();
126 $body['status'] = 'Deactivated';
127 $body['deactivated_date'] = time();
128
129 // Check deactivation reason and add for insights data.
130 if( false !== get_option( 'wpins_deactivation_reason_' . $this->plugin_name ) ) {
131 $body['deactivation_reason'] = get_option( 'wpins_deactivation_reason_' . $this->plugin_name );
132 }
133 if( false !== get_option( 'wpins_deactivation_details_' . $this->plugin_name ) ) {
134 $body['deactivation_details'] = get_option( 'wpins_deactivation_details_' . $this->plugin_name );
135 }
136
137 $this->send_data( $body );
138 delete_option( 'wpins_deactivation_reason_' . $this->plugin_name );
139 delete_option( 'wpins_deactivation_details_' . $this->plugin_name );
140 /**
141 * Clear the event schedule.
142 */
143 if( ! $this->disabled_wp_cron ) {
144 wp_clear_scheduled_hook( $this->event_hook );
145 }
146 }
147 /**
148 * Initial Method to Hook Everything.
149 * @return void
150 */
151 public function init(){
152 add_action( 'wpdeveloper_notice_clicked_for_' . $this->plugin_name, array( $this, 'clicked' ) );
153 add_action( $this->event_hook, array( $this, 'do_tracking' ) );
154 // For Test
155 // add_action( 'admin_init', array( $this, 'force_tracking' ) );
156 add_action( 'wpdeveloper_optin_notice_for_' . $this->plugin_name, array( $this, 'notice' ) );
157 /**
158 * Deactivation Reason Form and Submit Data to Insights.
159 */
160 add_filter( 'plugin_action_links_' . plugin_basename( $this->plugin_file ), array( $this, 'deactivate_action_links' ) );
161 add_action( 'admin_footer-plugins.php', array( $this, 'deactivate_reasons_form' ) );
162 add_action( 'wp_ajax_deactivation_form_' . esc_attr( $this->plugin_name ), array( $this, 'deactivate_reasons_form_submit' ) );
163 }
164 /**
165 * For Redirecting Current Page without Arguments!
166 *
167 * @return void
168 */
169 private function redirect_to(){
170 $request_uri = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_PATH );
171 $query_string = parse_url( $_SERVER['REQUEST_URI'], PHP_URL_QUERY );
172 parse_str( $query_string, $current_url );
173
174 $unset_array = array( 'dismiss', 'plugin', '_wpnonce', 'later', 'plugin_action', 'marketing_optin' );
175
176 foreach( $unset_array as $value ) {
177 if( isset( $current_url[ $value ] ) ) {
178 unset( $current_url[ $value ] );
179 }
180 }
181
182 $current_url = http_build_query($current_url);
183 $redirect_url = $request_uri;
184 if( $current_url ) {
185 $redirect_url .= '?' . $current_url;
186 }
187 return $redirect_url;
188 }
189 /**
190 * This method forcing the do_tracking method to execute instant.
191 * @return void
192 */
193 public function force_tracking(){
194 $this->do_tracking( true );
195 }
196 /**
197 * This method is responsible for all the magic from the front of the plugin.
198 * @since 3.0.0
199 * @param $force Force tracking if it's not the correct time to track/
200 */
201 public function do_tracking( $force = false ) {
202 /**
203 * Check URL is set or not.
204 */
205 if ( empty( self::API_URL ) ) {
206 return;
207 }
208 /**
209 * Check is tracking allowed or not.
210 */
211 if( ! $this->is_tracking_allowed() ) {
212 return;
213 }
214 /**
215 * Check is this the correct time to track or not.
216 * or Force to track.
217 */
218 if( ! $this->is_time_to_track() && ! $force ) {
219 return;
220 }
221 /**
222 * Get All Data.
223 */
224 $body = $this->get_data();
225 /**
226 * Send all data.
227 */
228 return $this->send_data( $body );
229 }
230 /**
231 * Is tracking allowed?
232 * @since 1.0.0
233 */
234 private function is_tracking_allowed() {
235 // First, check if the user has changed their mind and opted out of tracking
236 if( $this->has_user_opted_out() ) {
237 $this->set_is_tracking_allowed( false, $this->plugin_name );
238 return false;
239 }
240 // The wpins_allow_tracking option is an array of plugins that are being tracked
241 $allow_tracking = get_option( 'wpins_allow_tracking' );
242 // If this plugin is in the array, then tracking is allowed
243 if( isset( $allow_tracking[$this->plugin_name] ) ) {
244 return true;
245 }
246 return false;
247 }
248 /**
249 * Set a flag in DB If tracking is allowed.
250 *
251 * @since 3.0.0
252 * @param $is_allowed Boolean true if is allowed.
253 */
254 protected function set_is_tracking_allowed( $is_allowed, $plugin = null ) {
255 if( empty( $plugin ) ) {
256 $plugin = $this->plugin_name;
257 }
258 /**
259 * Get All Tracked Plugin List using this Tracker.
260 */
261 $allow_tracking = get_option( 'wpins_allow_tracking' );
262 /**
263 * Check user is opted out for tracking or not.
264 */
265 if( $this->has_user_opted_out() ) {
266 if( isset( $allow_tracking[$plugin] ) ) {
267 unset( $allow_tracking[$plugin] );
268 }
269 } else if( $is_allowed || ! $this->require_optin ) {
270 /**
271 * If user has agreed to allow tracking
272 */
273 if( empty( $allow_tracking ) || ! is_array( $allow_tracking ) ) {
274 $allow_tracking = array( $plugin => $plugin );
275 } else {
276 $allow_tracking[$plugin] = $plugin;
277 }
278 } else {
279 if( isset( $allow_tracking[$plugin] ) ) {
280 unset( $allow_tracking[$plugin] );
281 }
282 }
283 update_option( 'wpins_allow_tracking', $allow_tracking );
284 }
285
286 /**
287 * Check the user has opted out or not.
288 *
289 * @since 3.0.0
290 * @return Boolean
291 */
292 protected function has_user_opted_out() {
293 if( ! empty( $this->options ) ) {
294 foreach( $this->options as $option_name ) {
295 $options = get_option( $option_name );
296 if( ! empty( $options['wpins_opt_out'] ) ) {
297 return true;
298 }
299 }
300 }
301 return false;
302 }
303 /**
304 * Check if it's time to track
305 *
306 * @since 3.0.0
307 */
308 public function is_time_to_track() {
309 $track_times = get_option( 'wpins_last_track_time', array() );
310 return ! isset( $track_times[$this->plugin_name] ) ? true :
311 ( ( isset( $track_times[$this->plugin_name] ) && $track_times[$this->plugin_name] ) < strtotime( '-1 day' ) ? true : false );
312 }
313 /**
314 * Set tracking time.
315 *
316 * @since 3.0.0
317 */
318 public function set_track_time() {
319 $track_times = get_option( 'wpins_last_track_time', array() );
320 $track_times[ $this->plugin_name ] = time();
321 update_option( 'wpins_last_track_time', $track_times );
322 }
323 /**
324 * This method is responsible for collecting all data.
325 *
326 * @since 3.0.0
327 */
328 public function get_data() {
329 $body = array(
330 'plugin_slug' => sanitize_text_field( $this->plugin_name ),
331 'url' => get_bloginfo( 'url' ),
332 'site_name' => get_bloginfo( 'name' ),
333 'site_version' => get_bloginfo( 'version' ),
334 'site_language' => get_bloginfo( 'language' ),
335 'charset' => get_bloginfo( 'charset' ),
336 'wpins_version' => self::WPINS_VERSION,
337 'php_version' => phpversion(),
338 'multisite' => is_multisite(),
339 'file_location' => __FILE__
340 );
341
342 // Collect the email if the correct option has been set
343 if( $this->marketing ) {
344 if( ! function_exists( 'wp_get_current_user' ) ) {
345 include ABSPATH . 'wp-includes/pluggable.php';
346 }
347 $current_user = wp_get_current_user();
348 $email = $current_user->user_email;
349 if( is_email( $email ) ) {
350 $body['email'] = $email;
351 }
352 }
353 $body['marketing_method'] = $this->marketing;
354 $body['server'] = isset( $_SERVER['SERVER_SOFTWARE'] ) ? $_SERVER['SERVER_SOFTWARE'] : '';
355
356 /**
357 * Collect all active and inactive plugins
358 */
359 if( ! function_exists( 'get_plugins' ) ) {
360 include ABSPATH . '/wp-admin/includes/plugin.php';
361 }
362 $plugins = array_keys( get_plugins() );
363 $active_plugins = is_network_admin() ? array_keys( get_site_option( 'active_sitewide_plugins', array() ) ) : get_option( 'active_plugins', array() );
364 foreach ( $plugins as $key => $plugin ) {
365 if ( in_array( $plugin, $active_plugins ) ) {
366 unset( $plugins[$key] );
367 }
368 }
369 $body['active_plugins'] = $active_plugins;
370 $body['inactive_plugins'] = $plugins;
371
372 /**
373 * Text Direction.
374 */
375 $body['text_direction'] = ( function_exists( 'is_rtl' ) ? ( is_rtl() ? 'RTL' : 'LTR' ) : 'NOT SET' );
376 /**
377 * Get Our Plugin Data.
378 * @since 3.0.0
379 */
380 $plugin = $this->plugin_data();
381 if( empty( $plugin ) ) {
382 $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.', 'embedpress' );
383 $body['status'] = 'NOT FOUND';
384 } else {
385 if( isset( $plugin['Name'] ) ) {
386 $body['plugin'] = sanitize_text_field( $plugin['Name'] );
387 }
388 if( isset( $plugin['Version'] ) ) {
389 $body['version'] = sanitize_text_field( $plugin['Version'] );
390 }
391 $body['status'] = 'Active';
392 }
393
394 /**
395 * Get our plugin options
396 * @since 1.0.0
397 */
398 // $options = $this->options;
399 // $plugin_options = array();
400 // if( ! empty( $options ) && is_array( $options ) ) {
401 // foreach( $options as $option ) {
402 // $fields = get_option( $option );
403 // // Check for permission to send this option
404 // if( isset( $fields['wpins_registered_setting'] ) ) {
405 // foreach( $fields as $key=>$value ) {
406 // $plugin_options[$key] = $value;
407 // }
408 // }
409 // }
410 // }
411 // $body['plugin_options'] = $this->options; // Returns array
412 // $body['plugin_options_fields'] = $plugin_options; // Returns object
413
414 /**
415 * Get active theme name and version
416 * @since 3.0.0
417 */
418 $theme = wp_get_theme();
419 if( $theme->Name ) {
420 $body['theme'] = sanitize_text_field( $theme->Name );
421 }
422 if( $theme->Version ) {
423 $body['theme_version'] = sanitize_text_field( $theme->Version );
424 }
425 return $body;
426 }
427
428 /**
429 * Collect plugin data,
430 * Retrieve current plugin information
431 *
432 * @since 3.0.0
433 */
434 public function plugin_data() {
435 if( ! function_exists( 'get_plugin_data' ) ) {
436 include ABSPATH . '/wp-admin/includes/plugin.php';
437 }
438 $plugin = get_plugin_data( $this->plugin_file );
439 return $plugin;
440 }
441 /**
442 * Send the data to insights.
443 * @since 3.0.0
444 */
445 public function send_data( $body ) {
446 /**
447 * Get SITE ID
448 */
449 $site_id_key = "wpins_{$this->plugin_name}_site_id";
450 $site_id = get_option( $site_id_key, false );
451 $failed_data = [];
452 $site_url = get_bloginfo( 'url' );
453 $original_site_url = get_option( "wpins_{$this->plugin_name}_original_url", false );
454
455 if( ( $original_site_url === false || $original_site_url != $site_url ) && version_compare( $body['wpins_version'], '3.0.1', '>=' ) ) {
456 $site_id = false;
457 }
458 /**
459 * Send Initial Data to API
460 */
461 if( $site_id == false && $this->item_id !== false ) {
462 if( isset( $_SERVER['REMOTE_ADDR'] ) && ! empty( $_SERVER['REMOTE_ADDR'] && $_SERVER['REMOTE_ADDR'] != '127.0.0.1' ) ) {
463 $country_request = wp_remote_get( 'http://ip-api.com/json/'. $_SERVER['REMOTE_ADDR'] .'?fields=country');
464 if( ! is_wp_error( $country_request ) && $country_request['response']['code'] == 200 ) {
465 $ip_data = json_decode( $country_request["body"] );
466 $body['country'] = isset( $ip_data->country ) ? $ip_data->country : 'NOT SET';
467 }
468 }
469
470 $body['plugin_slug'] = $this->plugin_name;
471 $body['url'] = $site_url;
472 $body['item_id'] = $this->item_id;
473
474 $request = $this->remote_post( $body );
475 if( ! is_wp_error( $request ) && $request['response']['code'] == 200 ) {
476 $retrieved_body = json_decode( wp_remote_retrieve_body( $request ), true );
477 if( is_array( $retrieved_body ) && isset( $retrieved_body['siteId'] ) ) {
478 update_option( $site_id_key, $retrieved_body['siteId'] );
479 update_option( "wpins_{$this->plugin_name}_original_url", $site_url );
480 update_option( "wpins_{$this->plugin_name}_{$retrieved_body['siteId']}", $body );
481 }
482 } else {
483 $failed_data = $body;
484 }
485 }
486
487 $site_id_data_key = "wpins_{$this->plugin_name}_{$site_id}";
488 $site_id_data_failed_key = "wpins_{$this->plugin_name}_{$site_id}_send_failed";
489
490 if( $site_id != false ) {
491 $old_sent_data = get_option( $site_id_data_key, [] );
492 $diff_data = $this->diff( $body, $old_sent_data );
493 $failed_data = get_option( $site_id_data_failed_key, [] );
494 if( ! empty( $failed_data ) && $diff_data != $failed_data ) {
495 $failed_data = array_merge( $failed_data, $diff_data );
496 }
497 }
498
499 if( ! empty( $failed_data ) && $site_id != false ) {
500 $failed_data['plugin_slug'] = $this->plugin_name;
501 $failed_data['url'] = $site_url;
502 $failed_data['site_id'] = $site_id;
503 if( $original_site_url != false ) {
504 $failed_data['original_url'] = $original_site_url;
505 }
506
507 $request = $this->remote_post( $failed_data );
508 if( ! is_wp_error( $request ) ) {
509 delete_option( $site_id_data_failed_key );
510 $replaced_data = array_merge( $old_sent_data, $failed_data );
511 update_option( $site_id_data_key, $replaced_data );
512 }
513 }
514
515 if( ! empty( $diff_data ) && $site_id != false && empty( $failed_data ) ) {
516 $diff_data['plugin_slug'] = $this->plugin_name;
517 $diff_data['url'] = $site_url;
518 $diff_data['site_id'] = $site_id;
519 if( $original_site_url != false ) {
520 $diff_data['original_url'] = $original_site_url;
521 }
522
523 $request = $this->remote_post( $diff_data );
524 if( is_wp_error( $request ) ) {
525 update_option( $site_id_data_failed_key, $diff_data );
526 } else {
527 $replaced_data = array_merge( $old_sent_data, $diff_data );
528 update_option( $site_id_data_key, $replaced_data );
529 }
530 }
531
532 $this->set_track_time();
533
534 if( isset( $request ) && is_wp_error( $request ) ) {
535 return $request;
536 }
537
538 if( isset( $request ) ) {
539 return true;
540 }
541 return false;
542 }
543 /**
544 * WP_REMOTE_POST method responsible for send data to the API_URL
545 *
546 * @param array $data
547 * @param array $args
548 * @return void
549 */
550 protected function remote_post( $data = array(), $args = array() ){
551 if( empty( $data ) ) {
552 return;
553 }
554
555 $args = wp_parse_args( $args, array(
556 'method' => 'POST',
557 'timeout' => 30,
558 'redirection' => 5,
559 'httpversion' => '1.1',
560 'blocking' => true,
561 'body' => $data,
562 'user-agent' => 'PUT/1.0.0; ' . get_bloginfo( 'url' )
563 ));
564 $request = wp_remote_post( esc_url( self::API_URL ), $args );
565 if( is_wp_error( $request ) || ( isset( $request['response'], $request['response']['code'] ) && $request['response']['code'] != 200 ) ) {
566 return new WP_Error( 500, 'Something went wrong.' );
567 }
568 return $request;
569 }
570 /**
571 * Difference between old and new data
572 *
573 * @param array $new_data
574 * @param array $old_data
575 * @return void
576 */
577 protected function diff( $new_data, $old_data ){
578 $data = [];
579 if( ! empty( $new_data ) ) {
580 foreach( $new_data as $key => $value ) {
581 if( isset( $old_data[ $key ] ) ) {
582 if( $old_data[ $key ] == $value ) {
583 continue;
584 }
585 }
586 $data[ $key ] = $value;
587 }
588 }
589 return $data;
590 }
591 /**
592 * Display the admin notice to users to allow them to opt in
593 *
594 * @since 3.0.0
595 */
596 public function notice() {
597 /**
598 * Return if notice is not set.
599 */
600 if( ! isset( $this->notice_options['notice'] ) ) {
601 return;
602 }
603 /**
604 * Check is allowed or blocked for notice.
605 */
606 $block_notice = get_option( 'wpins_block_notice' );
607 if( isset( $block_notice[$this->plugin_name] ) ) {
608 return;
609 }
610
611 if( ! \function_exists('wp_get_current_user') ) {
612 require_once ABSPATH . "wp-includes/pluggable.php";
613 }
614
615 if ( ! current_user_can( 'manage_options' ) ) {
616 return;
617 }
618
619 $url_yes = add_query_arg( [
620 'plugin' => $this->plugin_name,
621 'plugin_action' => 'yes',
622 ] );
623 $url_no = add_query_arg( array(
624 'plugin' => $this->plugin_name,
625 'plugin_action' => 'no'
626 ) );
627
628 // Decide on notice text
629 $notice_text = $this->notice_options['notice'] . ' <a href="#" class="wpinsights-'. $this->plugin_name .'-collect">'. $this->notice_options['consent_button_text'] .'</a>';
630 $extra_notice_text = $this->notice_options['extra_notice'];
631
632 $output = '';
633 $output .= '<div class="embedpress-optin">';
634 $output .= '<p>'. $notice_text .'</p>';
635 $output .= '<div class="wpinsights-data" style="display: none;">';
636 $output .= '<p>'. $extra_notice_text .'</p>';
637 $output .= '</div>';
638 $output .= '<p>';
639 $output .= '<a href="'. esc_url( $url_yes ) .'" class="button-primary">'. $this->notice_options['yes'] .'</a>&nbsp;';
640 $output .= '<a href="'. esc_url( $url_no ) .'" class="button-secondary">'. $this->notice_options['no'] .'</a>';
641 $output .= '</p>';
642 $output .= "<script type='text/javascript'>jQuery('.wpinsights-". $this->plugin_name ."-collect').on('click', function(e) {e.preventDefault();jQuery('.wpinsights-data').slideToggle('fast');});</script>";
643 $output .= '</div>';
644
645 echo $output;
646 }
647 /**
648 * Set all notice options to customized notice.
649 *
650 * @since 3.0.0
651 * @param array $options
652 * @return void
653 */
654 public function set_notice_options( $options = [] ){
655 $default_options = [
656 'consent_button_text' => __( 'What we collect.', 'embedpress' ),
657 'yes' => __( 'Sure, I\'d like to help', 'embedpress' ),
658 'no' => __( 'No Thanks.', 'embedpress' ),
659 ];
660 $options = wp_parse_args( $options, $default_options );
661 $this->notice_options = $options;
662 }
663 /**
664 * Responsible for track the click from Notice.
665 * @return void
666 */
667 public function clicked( $notice = null ){
668 if( isset( $_GET['plugin'] ) && trim($_GET['plugin']) === $this->plugin_name && isset( $_GET['plugin_action'] ) ) {
669 if( isset( $_GET['tab'] ) && $_GET['tab'] === 'plugin-information' ) {
670 return;
671 }
672 $plugin = sanitize_text_field( $_GET['plugin'] );
673 $action = sanitize_text_field( $_GET['plugin_action'] );
674 if( $action == 'yes' ) {
675 $this->schedule_tracking();
676 $this->set_is_tracking_allowed( true, $plugin );
677 if( $this->do_tracking( true ) ) {
678 $this->update_block_notice( $plugin );
679 if( ! is_null ( $notice ) ) {
680 $notice->dismiss->dismiss_notice();
681 }
682 }
683 } else {
684 $this->set_is_tracking_allowed( false, $plugin );
685 $this->update_block_notice( $plugin );
686 if( ! is_null ( $notice ) ) {
687 $notice->dismiss->dismiss_notice();
688 }
689 }
690 /**
691 * Redirect User To the Current URL, but without set query arguments.
692 */
693 wp_safe_redirect( $this->redirect_to() );
694 }
695 }
696 /**
697 * Set if we should block the opt-in notice for this plugin
698 *
699 * @since 3.0.0
700 */
701 public function update_block_notice( $plugin = null ) {
702 if( empty( $plugin ) ) {
703 $plugin = $this->plugin_name;
704 }
705 $block_notice = get_option( 'wpins_block_notice' );
706 if( empty( $block_notice ) || ! is_array( $block_notice ) ) {
707 $block_notice = array( $plugin => $plugin );
708 } else {
709 $block_notice[$plugin] = $plugin;
710 }
711 update_option( 'wpins_block_notice', $block_notice );
712 }
713 /**
714 * AJAX callback when the deactivated form is submitted.
715 * @since 3.0.0
716 */
717 public function deactivate_reasons_form_submit() {
718 check_ajax_referer( 'wpins_deactivation_nonce', 'security' );
719 if( isset( $_POST['values'] ) ) {
720 $values = $_POST['values'];
721 update_option( 'wpins_deactivation_reason_' . $this->plugin_name, $values );
722 }
723 if( isset( $_POST['details'] ) ) {
724 $details = sanitize_text_field( $_POST['details'] );
725 update_option( 'wpins_deactivation_details_' . $this->plugin_name, $details );
726 }
727 echo 'success';
728 wp_die();
729 }
730 /**
731 * Filter the deactivation link to allow us to present a form when the user deactivates the plugin
732 * @since 3.0.0
733 */
734 public function deactivate_action_links( $links ) {
735 /**
736 * Check is tracking allowed or not.
737 */
738 if( ! $this->is_tracking_allowed() ) {
739 return $links;
740 }
741 if( isset( $links['deactivate'] ) && $this->include_goodbye_form ) {
742 $deactivation_link = $links['deactivate'];
743 /**
744 * Change the default deactivate button link.
745 */
746 $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 );
747 $links['deactivate'] = $deactivation_link;
748 }
749 return $links;
750 }
751 /**
752 * ALL Deactivate Reasons.
753 * @since 3.0.0
754 */
755 public function deactivation_reasons() {
756 $form = array();
757 $form['heading'] = __( 'Sorry to see you go', 'embedpress' );
758 $form['body'] = __( 'Before you deactivate the plugin, would you quickly give us your reason for doing so?', 'embedpress' );
759
760 $form['options'] = array(
761 __( 'I no longer need the plugin', 'embedpress' ),
762 [
763 'label' => __( 'I found a better plugin', 'embedpress' ),
764 'extra_field' => __( 'Please share which plugin', 'embedpress' )
765 ],
766 __( "I couldn't get the plugin to work", 'embedpress' ),
767 __( 'It\'s a temporary deactivation', 'embedpress' ),
768 [
769 'label' => __( 'Other', 'embedpress' ),
770 'extra_field' => __( 'Please share the reason', 'embedpress' ),
771 'type' => 'textarea'
772 ]
773 );
774 return apply_filters( 'wpins_form_text_' . $this->plugin_name, $form );
775 }
776 /**
777 * Deactivate Reasons Form.
778 * This form will appears when user wants to deactivate the plugin to send you deactivated reasons.
779 *
780 * @since 3.0.0
781 */
782 public function deactivate_reasons_form() {
783 $form = $this->deactivation_reasons();
784 $class_plugin_name = esc_attr( $this->plugin_name );
785 $html = '<div class="wpinsights-goodbye-form-head"><strong>' . esc_html( $form['heading'] ) . '</strong></div>';
786 $html .= '<div class="wpinsights-goodbye-form-body"><p class="wpinsights-goodbye-form-caption">' . esc_html( $form['body'] ) . '</p>';
787 if( is_array( $form['options'] ) ) {
788 $html .= '<div id="wpinsights-goodbye-options" class="wpinsights-goodbye-options"><ul>';
789 foreach( $form['options'] as $option ) {
790 if( is_array( $option ) ) {
791 $id = strtolower( str_replace( " ", "_", esc_attr( $option['label'] ) ) );
792 $id = $id . '_' . $class_plugin_name;
793 $html .= '<li class="has-goodbye-extra">';
794 $html .= '<input type="radio" name="wpinsights-'. $class_plugin_name .'-goodbye-options" id="' . $id . '" value="' . esc_attr( $option['label'] ) . '">';
795 $html .= '<div><label for="' . $id . '">' . esc_attr( $option['label'] ) . '</label>';
796 if( isset( $option[ 'extra_field' ] ) && ! isset( $option['type'] )) {
797 $html .= '<input type="text" style="display: none" name="'. $id .'" id="' . str_replace( " ", "", esc_attr( $option['extra_field'] ) ) . '" placeholder="' . esc_attr( $option['extra_field'] ) . '">';
798 }
799 if( isset( $option[ 'extra_field' ] ) && isset( $option['type'] )) {
800 $html .= '<'. $option['type'] .' style="display: none" type="text" name="'. $id .'" id="' . str_replace( " ", "", esc_attr( $option['extra_field'] ) ) . '" placeholder="' . esc_attr( $option['extra_field'] ) . '"></' . $option['type'] . '>';
801 }
802 $html .= '</div></li>';
803 } else {
804 $id = strtolower( str_replace( " ", "_", esc_attr( $option ) ) );
805 $id = $id . '_' . $class_plugin_name;
806 $html .= '<li><input type="radio" name="wpinsights-'. $class_plugin_name .'-goodbye-options" id="' . $id . '" value="' . esc_attr( $option ) . '"> <label for="' . $id . '">' . esc_attr( $option ) . '</label></li>';
807 }
808 }
809 $html .= '</ul></div><!-- .wpinsights-'. $class_plugin_name .'-goodbye-options -->';
810 }
811 $html .= '</div><!-- .wpinsights-goodbye-form-body -->';
812 $html .= '<p class="deactivating-spinner"><span class="spinner"></span> ' . __( 'Submitting form', 'embedpress' ) . '</p>';
813
814 $wrapper_class = '.wpinsights-goodbye-form-wrapper-'. $class_plugin_name;
815
816 $styles = '';
817 $styles .= '<style type="text/css">';
818 $styles .= '.wpinsights-form-active-' . $class_plugin_name . ' .wpinsights-goodbye-form-bg {';
819 $styles .= 'background: rgba( 0, 0, 0, .8 );position: fixed;top: 0;left: 0;width: 100%;height: 100%;z-index: 9;';
820 $styles .= '}';
821 $styles .= $wrapper_class . '{';
822 $styles .= 'position: relative; display: none;';
823 $styles .= '}';
824 $styles .= '.wpinsights-form-active-' . $class_plugin_name . ' ' . $wrapper_class . '{';
825 $styles .= 'display: flex !important; position: fixed;top: 0;left: 0;width: 100%;height: 100%; justify-content: center; align-items: center;';
826 $styles .= '}';
827 $styles .= $wrapper_class . ' .wpinsights-goodbye-form { display: none; }';
828 $styles .= '.wpinsights-form-active-' . $class_plugin_name . ' .wpinsights-goodbye-form {';
829 $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;';
830 $styles .= '}';
831 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-head {';
832 $styles .= 'background: #fff; color: #495157; padding: 18px; box-shadow: 0 0 8px rgba(0,0,0,.1); font-size: 15px;';
833 $styles .= '}';
834 $styles .= $wrapper_class . ' .wpinsights-goodbye-form .wpinsights-goodbye-form-head strong { font-size: 15px; }';
835 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body { padding: 8px 18px; color: #333; }';
836 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body label { padding-left: 5px; color: #6d7882; }';
837 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body .wpinsights-goodbye-form-caption {';
838 $styles .= 'font-weight: 500; font-size: 15px; color: #495157; line-height: 1.4;';
839 $styles .= '}';
840 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body #wpinsights-goodbye-options { padding-top: 5px; }';
841 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li { margin-bottom: 15px; }';
842 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-body #wpinsights-goodbye-options ul > li > div { display: inline; padding-left: 3px; }';
843 $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 {';
844 $styles .= 'margin: 10px 18px; padding: 8px; width: 80%;';
845 $styles .= '}';
846 $styles .= $wrapper_class . ' .deactivating-spinner { display: none; padding-bottom: 20px !important; }';
847 $styles .= $wrapper_class . ' .deactivating-spinner .spinner { float: none; margin: 4px 4px 0 18px; vertical-align: bottom; visibility: visible; }';
848 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer { padding: 8px 18px; margin-bottom: 15px; }';
849 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer > .wpinsights-goodbye-form-buttons { display: flex; align-items: center; justify-content: space-between; }';
850 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer .wpinsights-submit-btn {';
851 $styles .= 'background-color: #d30c5c; -webkit-border-radius: 3px; border-radius: 3px; color: #fff; line-height: 1; padding: 15px 20px; font-size: 13px;';
852 $styles .= '}';
853 $styles .= $wrapper_class . ' .wpinsights-goodbye-form-footer .wpinsights-deactivate-btn {';
854 $styles .= 'font-size: 13px; color: #a4afb7; background: none; float: right; padding-right: 10px; width: auto; text-decoration: underline;';
855 $styles .= '}';
856 $styles .= $wrapper_class . ' .test {';
857 $styles .= '}';
858 $styles .= '</style>';
859 $styles .= '';
860
861 echo $styles;
862 ?>
863 <script type="text/javascript">
864 jQuery(document).ready(function($){
865 $("#wpinsights-goodbye-link-<?php echo $class_plugin_name; ?>").on("click",function(){
866 // We'll send the user to this deactivation link when they've completed or dismissed the form
867 var url = document.getElementById("wpinsights-goodbye-link-<?php echo $class_plugin_name; ?>");
868 $('body').toggleClass('wpinsights-form-active-<?php echo $class_plugin_name; ?>');
869 $(".wpinsights-goodbye-form-wrapper-<?php echo $class_plugin_name; ?> #wpinsights-goodbye-form").fadeIn();
870 $(".wpinsights-goodbye-form-wrapper-<?php echo $class_plugin_name; ?> #wpinsights-goodbye-form").html( '<?php echo $html; ?>' + '<div class="wpinsights-goodbye-form-footer"><div class="wpinsights-goodbye-form-buttons"><a id="wpinsights-submit-form-<?php echo $class_plugin_name; ?>" class="wpinsights-submit-btn" href="#"><?php _e( 'Submit and Deactivate', 'embedpress' ); ?></a>&nbsp;<a class="wpsp-put-deactivate-btn" href="'+url+'"><?php _e( 'Just Deactivate', 'embedpress' ); ?></a></div></div>');
871 $('#wpinsights-submit-form-<?php echo $class_plugin_name; ?>').on('click', function(e){
872 // As soon as we click, the body of the form should disappear
873 $("#wpinsights-goodbye-form-<?php echo $class_plugin_name; ?> .wpinsights-goodbye-form-body").fadeOut();
874 $("#wpinsights-goodbye-form-<?php echo $class_plugin_name; ?> .wpinsights-goodbye-form-footer").fadeOut();
875 // Fade in spinner
876 $("#wpinsights-goodbye-form-<?php echo $class_plugin_name; ?> .deactivating-spinner").fadeIn();
877 e.preventDefault();
878 var checkedInput = $("input[name='wpinsights-<?php echo $class_plugin_name; ?>-goodbye-options']:checked"),
879 checkedInputVal, details;
880 if( checkedInput.length > 0 ) {
881 checkedInputVal = checkedInput.val();
882 details = $('input[name="'+ checkedInput[0].id +'"], textarea[name="'+ checkedInput[0].id +'"]').val();
883 }
884
885 if( typeof details === 'undefined' ) {
886 details = '';
887 }
888 if( typeof checkedInputVal === 'undefined' ) {
889 checkedInputVal = 'No Reason';
890 }
891
892 var data = {
893 'action': 'deactivation_form_<?php echo $class_plugin_name; ?>',
894 'values': checkedInputVal,
895 'details': details,
896 'security': "<?php echo wp_create_nonce ( 'wpins_deactivation_nonce' ); ?>",
897 'dataType': "json"
898 }
899
900 $.post(
901 ajaxurl,
902 data,
903 function(response){
904 // Redirect to original deactivation URL
905 window.location.href = url;
906 }
907 );
908 });
909 $('#wpinsights-goodbye-options > ul ').on('click', 'li label, li > input', function( e ){
910 var parent = $(this).parents('li');
911 parent.siblings().find('label').next('input, textarea').css('display', 'none');
912 parent.find('label').next('input, textarea').css('display', 'block');
913 });
914 // If we click outside the form, the form will close
915 $('.wpinsights-goodbye-form-bg').on('click',function(){
916 $("#wpinsights-goodbye-form").fadeOut();
917 $('body').removeClass('wpinsights-form-active-<?php echo $class_plugin_name; ?>');
918 });
919 });
920 });
921 </script>
922 <?php }
923 }
924 endif;