| 1 |
<?php |
| 2 |
/** |
| 3 |
* WebAppick Insights |
| 4 |
* |
| 5 |
* @version 1.0.1 |
| 6 |
* @package Disco |
| 7 |
* @subpackage AppServices |
| 8 |
* |
| 9 |
* This is a tracker class to track plugin usage based on if the customer has opted in. |
| 10 |
* No personal information is being tracked by this class, only general settings, active plugins, environment details |
| 11 |
* and admin email. |
| 12 |
*/ |
| 13 |
|
| 14 |
namespace Disco\Libs\WebAppick\AppServices; |
| 15 |
|
| 16 |
use Exception; |
| 17 |
use WP_Theme; |
| 18 |
use WP_User; |
| 19 |
|
| 20 |
if ( ! defined( 'ABSPATH' ) ) { |
| 21 |
die(); |
| 22 |
} |
| 23 |
|
| 24 |
/** |
| 25 |
* Class Insights |
| 26 |
*/ |
| 27 |
class Insights { |
| 28 |
|
| 29 |
/** |
| 30 |
* The notice text |
| 31 |
* |
| 32 |
* @var string |
| 33 |
*/ |
| 34 |
protected $notice; |
| 35 |
|
| 36 |
/** |
| 37 |
* Whether to the notice or not |
| 38 |
* |
| 39 |
* @var boolean |
| 40 |
*/ |
| 41 |
protected $show_notice = true; |
| 42 |
|
| 43 |
/** |
| 44 |
* If extra data needs to be sent |
| 45 |
* |
| 46 |
* @var array |
| 47 |
*/ |
| 48 |
protected $extra_data = array(); |
| 49 |
|
| 50 |
/** |
| 51 |
* CTXFeed\AppServices\Client |
| 52 |
* |
| 53 |
* @var Client |
| 54 |
*/ |
| 55 |
protected $client; |
| 56 |
|
| 57 |
/** |
| 58 |
* Flag for checking if the init method is already called. |
| 59 |
* @var bool |
| 60 |
*/ |
| 61 |
private $didInit = false; |
| 62 |
|
| 63 |
/** |
| 64 |
* Email Message Template For sending Support Ticket |
| 65 |
* @var string |
| 66 |
*/ |
| 67 |
protected $ticketTemplate = ''; |
| 68 |
|
| 69 |
/** |
| 70 |
* Ticket Email Recipient |
| 71 |
* @var string |
| 72 |
*/ |
| 73 |
protected $ticketRecipient = ''; |
| 74 |
|
| 75 |
/** |
| 76 |
* Response to show after support ticket submitted. |
| 77 |
* @var string |
| 78 |
*/ |
| 79 |
protected $supportResponse = ''; |
| 80 |
|
| 81 |
/** |
| 82 |
* Error Response for the support ticket |
| 83 |
* @var string |
| 84 |
*/ |
| 85 |
protected $supportErrorResponse = ''; |
| 86 |
|
| 87 |
/** |
| 88 |
* Support Page URL |
| 89 |
* @var string |
| 90 |
*/ |
| 91 |
protected $supportURL = ''; |
| 92 |
|
| 93 |
/** |
| 94 |
* Initialize the class |
| 95 |
* |
| 96 |
* @param Client $client The client. |
| 97 |
* @param string $name readable name of the Plugin/Theme. |
| 98 |
* @param string $file main Plugin/Theme file path. |
| 99 |
*/ |
| 100 |
public function __construct( $client, $name = null, $file = null ) { |
| 101 |
if ( is_string( $client ) && ! empty( $name ) && ! empty( $file ) ) { |
| 102 |
$client = new Client( $client, $name, $file ); |
| 103 |
} |
| 104 |
|
| 105 |
if ( is_object( $client ) && is_a( $client, 'Disco\Libs\WebAppick\AppServices\Client' ) ) { |
| 106 |
$this->client = $client; |
| 107 |
} |
| 108 |
} |
| 109 |
|
| 110 |
/** |
| 111 |
* Don't show the notice |
| 112 |
* |
| 113 |
* @return Insights |
| 114 |
*/ |
| 115 |
public function hide_notice() { |
| 116 |
$this->show_notice = false; |
| 117 |
return $this; |
| 118 |
} |
| 119 |
|
| 120 |
/** |
| 121 |
* Add extra data if needed |
| 122 |
* |
| 123 |
* @param array $data Extra data. |
| 124 |
* |
| 125 |
* @return Insights |
| 126 |
*/ |
| 127 |
public function add_extra( $data = array() ) { |
| 128 |
$this->extra_data = $data; |
| 129 |
|
| 130 |
return $this; |
| 131 |
} |
| 132 |
|
| 133 |
/** |
| 134 |
* Set custom notice text |
| 135 |
* |
| 136 |
* @param string $text Admin Notice Test. |
| 137 |
* |
| 138 |
* @return Insights |
| 139 |
*/ |
| 140 |
public function notice( $text ) { |
| 141 |
$this->notice = $text; |
| 142 |
|
| 143 |
return $this; |
| 144 |
} |
| 145 |
|
| 146 |
/** |
| 147 |
* Initialize insights |
| 148 |
* |
| 149 |
* @return void |
| 150 |
*/ |
| 151 |
public function init() { |
| 152 |
// Env Setup. |
| 153 |
$projectSlug = $this->client->getSlug(); |
| 154 |
/** |
| 155 |
* Support Page URL |
| 156 |
* @param string $supportURL |
| 157 |
*/ |
| 158 |
$supportURL = apply_filters( "WebAppick_{$projectSlug}_Support_Page_URL" , false ); |
| 159 |
if ( FALSE !== $supportURL ) { |
| 160 |
$supportURL = esc_url_raw( $supportURL, [ 'http', 'https' ] ); |
| 161 |
if ( ! empty( $supportURL ) ) { |
| 162 |
$this->supportURL = $supportURL; |
| 163 |
} |
| 164 |
} |
| 165 |
/** |
| 166 |
* Set Ticket Recipient Email |
| 167 |
* @param string $ticketRecipient |
| 168 |
*/ |
| 169 |
$ticketRecipient = apply_filters( "WebAppick_{$projectSlug}_Support_Ticket_Recipient_Email" , false ); |
| 170 |
if ( FALSE !== $ticketRecipient && is_email( $ticketRecipient ) ) { |
| 171 |
$this->ticketRecipient = sanitize_email( $ticketRecipient ); |
| 172 |
} |
| 173 |
/** |
| 174 |
* Set Support Ticket Template For sending the email query. |
| 175 |
* @param string $ticketTemplate |
| 176 |
*/ |
| 177 |
$ticketTemplate = apply_filters( "WebAppick_{$projectSlug}_Support_Ticket_Email_Template", false ); |
| 178 |
if ( FALSE !== $ticketTemplate ) { |
| 179 |
$this->ticketTemplate = $ticketTemplate; |
| 180 |
} |
| 181 |
|
| 182 |
// initialize. |
| 183 |
if ( $this->client->getType() == 'plugin' ) { |
| 184 |
$this->init_plugin(); |
| 185 |
} elseif ( $this->client->getType() == 'theme' ) { |
| 186 |
$this->init_theme(); |
| 187 |
} |
| 188 |
$this->didInit = true; |
| 189 |
} |
| 190 |
|
| 191 |
/** |
| 192 |
* Initialize theme hooks |
| 193 |
* |
| 194 |
* @return void |
| 195 |
*/ |
| 196 |
private function init_theme() { |
| 197 |
$this->init_common(); |
| 198 |
|
| 199 |
add_action( 'switch_theme', [ $this, 'deactivation_cleanup' ] ); |
| 200 |
add_action( 'switch_theme', [ $this, 'theme_deactivated' ], 12, 3 ); |
| 201 |
} |
| 202 |
|
| 203 |
/** |
| 204 |
* Initialize plugin hooks |
| 205 |
* |
| 206 |
* @return void |
| 207 |
*/ |
| 208 |
private function init_plugin() { |
| 209 |
// plugin deactivate popup. |
| 210 |
if ( ! $this->__is_local_server() ) { |
| 211 |
add_action( 'plugin_action_links_' . $this->client->getBasename(), [ $this, 'plugin_action_links' ] ); |
| 212 |
add_action( 'admin_footer', [ $this, 'deactivate_scripts' ] ); |
| 213 |
} |
| 214 |
|
| 215 |
$this->init_common(); |
| 216 |
|
| 217 |
register_activation_hook( $this->client->getFile(), [ $this, 'activate_plugin' ] ); |
| 218 |
register_deactivation_hook( $this->client->getFile(), [ $this, 'deactivation_cleanup' ] ); |
| 219 |
} |
| 220 |
|
| 221 |
/** |
| 222 |
* Initialize common hooks |
| 223 |
* |
| 224 |
* @return void |
| 225 |
*/ |
| 226 |
protected function init_common() { |
| 227 |
if ( $this->show_notice ) { |
| 228 |
// tracking notice. |
| 229 |
add_action( 'admin_notices', [ $this, 'admin_notice' ] ); |
| 230 |
} |
| 231 |
add_action( 'admin_init', [ $this, 'handle_optIn_optOut' ] ); |
| 232 |
add_action( 'removable_query_args', [ $this, 'add_removable_query_args' ], 10, 1 ); |
| 233 |
// uninstall reason. |
| 234 |
add_action( 'wp_ajax_' . $this->client->getSlug() . '_submit-uninstall-reason', [ $this, 'uninstall_reason_submission' ] ); |
| 235 |
add_action( 'wp_ajax_' . $this->client->getSlug() . '_submit-support-ticket', [ $this, 'support_ticket_submission' ] ); |
| 236 |
// cron events. |
| 237 |
add_filter( 'cron_schedules', [ $this, 'add_weekly_schedule' ] ); |
| 238 |
add_action( $this->client->getSlug() . '_tracker_send_event', [ $this, 'send_tracking_data' ] ); |
| 239 |
} |
| 240 |
|
| 241 |
/** |
| 242 |
* Send tracking data to WebAppick server |
| 243 |
* |
| 244 |
* @param boolean $override override current settings. |
| 245 |
* |
| 246 |
* @return void |
| 247 |
*/ |
| 248 |
public function send_tracking_data( $override = false ) { |
| 249 |
// skip on AJAX Requests. |
| 250 |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { |
| 251 |
return; |
| 252 |
} |
| 253 |
if ( ! $this->is_tracking_allowed() && ! $override ) { |
| 254 |
return; |
| 255 |
} |
| 256 |
// Send a maximum of once per week. |
| 257 |
$last_send = $this->__get_last_send(); |
| 258 |
/** |
| 259 |
* Tracking interval |
| 260 |
* |
| 261 |
* @param string $interval A valid date/time string |
| 262 |
* |
| 263 |
* @see strtotime() |
| 264 |
* @link https://www.php.net/manual/en/function.strtotime.php |
| 265 |
*/ |
| 266 |
$trackingInterval = apply_filters( $this->client->getSlug() . '_tracking_interval', '-1 week' ); |
| 267 |
try { |
| 268 |
$intervalCheck = strtotime( $trackingInterval ); |
| 269 |
} catch ( Exception $e ) { |
| 270 |
// fallback to default 1 week if filter returned unusable data. |
| 271 |
$intervalCheck = strtotime( '-1 week' ); |
| 272 |
} |
| 273 |
if ( $last_send && $last_send > $intervalCheck && ! $override ) { |
| 274 |
return; |
| 275 |
} |
| 276 |
$this->client->send_request( $this->get_tracking_data(), 'track' ); |
| 277 |
update_option( $this->client->getSlug() . '_tracking_last_send', time(), false ); |
| 278 |
} |
| 279 |
|
| 280 |
/** |
| 281 |
* Get the tracking data points |
| 282 |
* |
| 283 |
* @return array |
| 284 |
*/ |
| 285 |
protected function get_tracking_data() { |
| 286 |
$all_plugins = $this->__get_all_plugins(); |
| 287 |
$admin_user = $this->__get_admin(); |
| 288 |
$store_country = get_option('woocommerce_default_country'); |
| 289 |
$admin_emails = [ get_option( 'admin_email' ), $admin_user->user_email ]; |
| 290 |
$admin_emails = array_filter( $admin_emails ); |
| 291 |
$admin_emails = array_unique( $admin_emails ); |
| 292 |
$data = [ |
| 293 |
'version' => $this->client->getProjectVersion(), |
| 294 |
'url' => esc_url( home_url() ), |
| 295 |
'site' => $this->__get_site_name(), |
| 296 |
'admin_email' => implode( ',', $admin_emails ), |
| 297 |
'first_name' => $admin_user->first_name ? $admin_user->first_name : $admin_user->display_name, |
| 298 |
'last_name' => $admin_user->last_name, |
| 299 |
'plugin' => $this->client->getName(), |
| 300 |
'hash' => $this->client->getHash(), |
| 301 |
'server' => $this->__get_server_info(), |
| 302 |
'wp' => $this->__get_wp_info(), |
| 303 |
'active_plugins' => $all_plugins['active_plugins'], |
| 304 |
'inactive_plugins' => $all_plugins['inactive_plugins'], |
| 305 |
'ip_address' => $this->__get_user_ip_address(), |
| 306 |
'theme' => get_stylesheet(), |
| 307 |
'country' => $store_country |
| 308 |
]; |
| 309 |
// for child classes. |
| 310 |
$extra = $this->get_extra_data(); |
| 311 |
if ( ! empty( $extra ) ) { |
| 312 |
$data['extra'] = $extra; |
| 313 |
} |
| 314 |
|
| 315 |
return apply_filters( $this->client->getSlug() . '_tracker_data', $data ); |
| 316 |
} |
| 317 |
|
| 318 |
/** |
| 319 |
* If a child class wants to send extra data |
| 320 |
* |
| 321 |
* @return mixed |
| 322 |
*/ |
| 323 |
protected function get_extra_data() { |
| 324 |
return $this->extra_data; |
| 325 |
} |
| 326 |
|
| 327 |
/** |
| 328 |
* Explain the user which data we collect |
| 329 |
* |
| 330 |
* @return array |
| 331 |
*/ |
| 332 |
protected function data_we_collect() { |
| 333 |
$data = [ |
| 334 |
esc_html__( 'Server environment details (php, mysql, server, WordPress versions).', 'disco' ), |
| 335 |
]; |
| 336 |
$data = apply_filters( $this->client->getSlug() . '_what_tracked', $data ); |
| 337 |
|
| 338 |
return $data; |
| 339 |
} |
| 340 |
|
| 341 |
/** |
| 342 |
* Get the message array of what data being collected |
| 343 |
* @return array |
| 344 |
*/ |
| 345 |
public function get_data_collection_description() { |
| 346 |
return $this->data_we_collect(); |
| 347 |
} |
| 348 |
|
| 349 |
/** |
| 350 |
* Get Site SuperAdmin |
| 351 |
* Returns Empty WP_User instance if fails |
| 352 |
* @return WP_User |
| 353 |
*/ |
| 354 |
private function __get_admin() { |
| 355 |
$admins = get_users( |
| 356 |
[ |
| 357 |
'role' => 'administrator', |
| 358 |
'orderby' => 'ID', |
| 359 |
'order' => 'ASC', |
| 360 |
'number' => 1, |
| 361 |
'paged' => 1, |
| 362 |
] |
| 363 |
); |
| 364 |
|
| 365 |
return ( is_array( $admins ) && ! empty( $admins ) ) ? $admins[0] : new WP_User(); |
| 366 |
} |
| 367 |
|
| 368 |
/** |
| 369 |
* Check if the user has opted into tracking |
| 370 |
* |
| 371 |
* @return bool |
| 372 |
*/ |
| 373 |
public function is_tracking_allowed() { |
| 374 |
return 'yes' == get_option( $this->client->getSlug() . '_allow_tracking', 'no' ); |
| 375 |
} |
| 376 |
|
| 377 |
/** |
| 378 |
* Get the last time a tracking was sent |
| 379 |
* |
| 380 |
* @return false|int |
| 381 |
*/ |
| 382 |
private function __get_last_send() { |
| 383 |
return get_option( $this->client->getSlug() . '_tracking_last_send', false ); |
| 384 |
} |
| 385 |
|
| 386 |
/** |
| 387 |
* Check if the notice has been dismissed or enabled |
| 388 |
* |
| 389 |
* @return boolean |
| 390 |
*/ |
| 391 |
private function __notice_dismissed() { |
| 392 |
$hide_notice = get_option( $this->client->getSlug() . '_tracking_notice', 'no' ); |
| 393 |
if ( 'hide' == $hide_notice ) { |
| 394 |
return true; |
| 395 |
} |
| 396 |
|
| 397 |
return false; |
| 398 |
} |
| 399 |
|
| 400 |
/** |
| 401 |
* Check if the current server is localhost |
| 402 |
* |
| 403 |
* @return boolean |
| 404 |
*/ |
| 405 |
public function __is_local_server() { |
| 406 |
// phpcs:disable |
| 407 |
return apply_filters( 'WebAppick_is_local', isset( $_SERVER['REMOTE_ADDR'] ) ? in_array( $_SERVER['REMOTE_ADDR'], [ '127.0.0.1', '::1' ] ) : true ); |
| 408 |
// phpcs:enable |
| 409 |
} |
| 410 |
|
| 411 |
/** |
| 412 |
* Schedule the event weekly |
| 413 |
* |
| 414 |
* @return void |
| 415 |
*/ |
| 416 |
private function __schedule_event() { |
| 417 |
$hook_name = $this->client->getSlug() . '_tracker_send_event'; |
| 418 |
if ( ! wp_next_scheduled( $hook_name ) ) { |
| 419 |
wp_schedule_event( time(), 'weekly', $hook_name ); |
| 420 |
} |
| 421 |
} |
| 422 |
|
| 423 |
/** |
| 424 |
* Clear any scheduled hook |
| 425 |
* |
| 426 |
* @return void |
| 427 |
*/ |
| 428 |
private function __clear_schedule_event() { |
| 429 |
wp_clear_scheduled_hook( $this->client->getSlug() . '_tracker_send_event' ); |
| 430 |
} |
| 431 |
|
| 432 |
/** |
| 433 |
* Display the admin notice to users that have not opted-in or out |
| 434 |
* |
| 435 |
* @return void |
| 436 |
*/ |
| 437 |
public function admin_notice() { |
| 438 |
if ( $this->__notice_dismissed() ) { |
| 439 |
return; |
| 440 |
} |
| 441 |
|
| 442 |
if ( $this->is_tracking_allowed() ) { |
| 443 |
return; |
| 444 |
} |
| 445 |
if ( ! current_user_can( 'manage_options' ) ) { |
| 446 |
return; |
| 447 |
} |
| 448 |
|
| 449 |
// don't show tracking if a local server. |
| 450 |
if ( ! $this->__is_local_server() ) { |
| 451 |
|
| 452 |
if ( empty( $this->notice ) ) { |
| 453 |
$notice = sprintf( |
| 454 |
apply_filters( |
| 455 |
$this->client->getSlug() . '_tracking_default_notice_message', |
| 456 |
/* translators: 1: plugin name */ |
| 457 |
esc_html__( 'Want to help make %1$s even more awesome? Allow %1$s to collect non-sensitive diagnostic data and usage information.', 'disco' ) |
| 458 |
), |
| 459 |
'<strong>' . esc_html( $this->client->getName() ) . '</strong>' |
| 460 |
); |
| 461 |
} else { |
| 462 |
$notice = $this->notice; |
| 463 |
} |
| 464 |
|
| 465 |
$notice .= ' (<a class="' . $this->client->getSlug() . '-insights-data-we-collect" href="#">' . esc_html__( 'what we collect', 'disco' ) . '</a>)'; |
| 466 |
$notice .= '<p class="description" style="display:none;">' . implode( ', ', $this->data_we_collect() ) . '. ' . esc_html__( 'No sensitive data is tracked.', 'disco' ) . '</p>'; |
| 467 |
echo '<div class="updated"><p>'; |
| 468 |
echo wp_kses_post($notice); // phpcs:ignore xss ok |
| 469 |
echo '</p><p class="submit">'; |
| 470 |
echo ' <a href="' . esc_url( $this->get_opt_out_url() ) . '" class="disco-notice-secondary-button">' . esc_html__( 'No thanks', 'disco' ) . '</a>'; |
| 471 |
echo ' <a href="' . esc_url( $this->get_opt_in_url() ) . '" class="disco-notice-primary-button">' . esc_html__( 'Allow', 'disco' ) . '</a>'; |
| 472 |
echo '</p></div>'; |
| 473 |
echo "<script type='text/javascript'>jQuery('." . esc_attr( $this->client->getSlug() ) . "-insights-data-we-collect').on('click', function(e) { |
| 474 |
e.preventDefault(); |
| 475 |
jQuery(this).parents('.updated').find('p.description').slideToggle('fast'); |
| 476 |
});</script>"; |
| 477 |
} |
| 478 |
} |
| 479 |
|
| 480 |
/** |
| 481 |
* Tracking Opt In URL |
| 482 |
* @return string |
| 483 |
*/ |
| 484 |
public function get_opt_in_url() { |
| 485 |
return add_query_arg( |
| 486 |
[ |
| 487 |
$this->client->getSlug() . '_tracker_optIn' => 'true', |
| 488 |
'_wpnonce' => wp_create_nonce( $this->client->getSlug() . '_insight_action' ), |
| 489 |
] |
| 490 |
); |
| 491 |
} |
| 492 |
|
| 493 |
/** |
| 494 |
* Tracking Opt Out URL |
| 495 |
* @return string |
| 496 |
*/ |
| 497 |
public function get_opt_out_url() { |
| 498 |
return add_query_arg( |
| 499 |
[ |
| 500 |
$this->client->getSlug() . '_tracker_optOut' => 'true', |
| 501 |
'_wpnonce' => wp_create_nonce( $this->client->getSlug() . '_insight_action' ), |
| 502 |
] |
| 503 |
); |
| 504 |
} |
| 505 |
|
| 506 |
/** |
| 507 |
* handle the optIn/optOut |
| 508 |
* |
| 509 |
* @return void |
| 510 |
*/ |
| 511 |
public function handle_optIn_optOut() { |
| 512 |
if ( isset( $_REQUEST['_wpnonce'] ) && ( isset( $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) || isset( $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) ) ) { |
| 513 |
check_admin_referer( $this->client->getSlug() . '_insight_action' ); |
| 514 |
if ( isset( $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) && 'true' == $_GET[ $this->client->getSlug() . '_tracker_optIn' ] ) { |
| 515 |
$this->optIn(); |
| 516 |
wp_safe_redirect( remove_query_arg( $this->client->getSlug() . '_tracker_optIn' ) ); |
| 517 |
exit; |
| 518 |
} |
| 519 |
if ( isset( $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) && 'true' == $_GET[ $this->client->getSlug() . '_tracker_optOut' ] ) { |
| 520 |
$this->optOut(); |
| 521 |
wp_safe_redirect( remove_query_arg( $this->client->getSlug() . '_tracker_optOut' ) ); |
| 522 |
exit; |
| 523 |
} |
| 524 |
} |
| 525 |
} |
| 526 |
|
| 527 |
/** |
| 528 |
* Add query vars to removable query args array |
| 529 |
* |
| 530 |
* @param array $removable_query_args array of removable args. |
| 531 |
* |
| 532 |
* @return array |
| 533 |
*/ |
| 534 |
public function add_removable_query_args( $removable_query_args ) { |
| 535 |
return array_merge( |
| 536 |
$removable_query_args, |
| 537 |
[ $this->client->getSlug() . '_tracker_optIn', $this->client->getSlug() . '_tracker_optOut', '_wpnonce' ] |
| 538 |
); |
| 539 |
} |
| 540 |
|
| 541 |
/** |
| 542 |
* Tracking optIn |
| 543 |
* |
| 544 |
* @param bool $override optional. set send tracking data override setting, ignore last send datetime setting if true. |
| 545 |
* |
| 546 |
* @return void |
| 547 |
* @see Insights::send_tracking_data() |
| 548 |
*/ |
| 549 |
public function optIn( $override = false ) { |
| 550 |
update_option( $this->client->getSlug() . '_allow_tracking', 'yes', false ); |
| 551 |
update_option( $this->client->getSlug() . '_tracking_notice', 'hide', false ); |
| 552 |
$this->__clear_schedule_event(); |
| 553 |
$this->__schedule_event(); |
| 554 |
$this->send_tracking_data( $override ); |
| 555 |
} |
| 556 |
|
| 557 |
/** |
| 558 |
* optOut from tracking |
| 559 |
* |
| 560 |
* @return void |
| 561 |
*/ |
| 562 |
public function optOut() { |
| 563 |
update_option( $this->client->getSlug() . '_allow_tracking', 'no', false ); |
| 564 |
update_option( $this->client->getSlug() . '_tracking_notice', 'hide', false ); |
| 565 |
$this->__clear_schedule_event(); |
| 566 |
} |
| 567 |
|
| 568 |
/** |
| 569 |
* Get the number of post counts |
| 570 |
* |
| 571 |
* @param string $post_type PostType name to get count for. |
| 572 |
* |
| 573 |
* @return integer |
| 574 |
*/ |
| 575 |
public function get_post_count( $post_type ) { |
| 576 |
global $wpdb; |
| 577 |
// phpcs:disable |
| 578 |
return (int) $wpdb->get_var( |
| 579 |
$wpdb->prepare( |
| 580 |
"SELECT count(ID) FROM $wpdb->posts WHERE post_type = %s and post_status = 'publish'", |
| 581 |
$post_type |
| 582 |
) |
| 583 |
); |
| 584 |
// phpcs:enable |
| 585 |
} |
| 586 |
|
| 587 |
/** |
| 588 |
* Get server related info. |
| 589 |
* |
| 590 |
* @return array |
| 591 |
*/ |
| 592 |
private function __get_server_info() { |
| 593 |
global $wpdb; |
| 594 |
$server_data = [ |
| 595 |
'software' => ( isset( $_SERVER['SERVER_SOFTWARE'] ) && ! empty( $_SERVER['SERVER_SOFTWARE'] ) ) ? sanitize_text_field( $_SERVER['SERVER_SOFTWARE'] ) : 'N/A', |
| 596 |
'php_version' => ( function_exists( 'phpversion' ) ) ? phpversion() : 'N/A', |
| 597 |
'mysql_version' => $wpdb->db_version(), |
| 598 |
'php_execution_time' => @ini_get( 'max_execution_time' ), // phpcs:ignore |
| 599 |
'php_max_upload_size' => size_format( wp_max_upload_size() ), |
| 600 |
'php_default_timezone' => date_default_timezone_get(), |
| 601 |
'php_soap' => class_exists( 'SoapClient' ) ? 'Yes' : 'No', |
| 602 |
'php_fsockopen' => function_exists( 'fsockopen' ) ? 'Yes' : 'No', |
| 603 |
'php_curl' => function_exists( 'curl_init' ) ? 'Yes' : 'No', |
| 604 |
'php_ftp' => function_exists( 'ftp_connect' ) ? 'Yes' : 'No', |
| 605 |
'php_sftp' => function_exists( 'ssh2_connect' ) ? 'Yes' : 'No', |
| 606 |
]; |
| 607 |
|
| 608 |
return $server_data; |
| 609 |
} |
| 610 |
|
| 611 |
/** |
| 612 |
* Get WordPress related data. |
| 613 |
* |
| 614 |
* @return array |
| 615 |
*/ |
| 616 |
private function __get_wp_info() { |
| 617 |
$wp_data = [ |
| 618 |
'memory_limit' => WP_MEMORY_LIMIT, |
| 619 |
'debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ) ? 'Yes' : 'No', |
| 620 |
'locale' => get_locale(), |
| 621 |
'version' => get_bloginfo( 'version' ), |
| 622 |
'multisite' => is_multisite() ? 'Yes' : 'No', |
| 623 |
]; |
| 624 |
|
| 625 |
return $wp_data; |
| 626 |
} |
| 627 |
|
| 628 |
/** |
| 629 |
* Get the list of active and inactive plugins |
| 630 |
* @return array |
| 631 |
*/ |
| 632 |
private function __get_all_plugins() { |
| 633 |
if ( ! function_exists( 'get_plugins' ) ) { |
| 634 |
include ABSPATH . '/wp-admin/includes/plugin.php'; |
| 635 |
} |
| 636 |
$plugins = get_plugins(); |
| 637 |
$active_plugins = []; |
| 638 |
$active_plugins_keys = get_option( 'active_plugins', [] ); |
| 639 |
foreach ( $plugins as $k => $v ) { |
| 640 |
// Take care of formatting the data how we want it. |
| 641 |
$formatted = [ |
| 642 |
'name' => isset( $v['Name'] ) ? wp_strip_all_tags( $v['Name'] ) : '', |
| 643 |
'version' => isset( $v['Version'] ) ? wp_strip_all_tags( $v['Version'] ) : 'N/A', |
| 644 |
'author' => isset( $v['Author'] ) ? wp_strip_all_tags( $v['Author'] ) : 'N/A', |
| 645 |
'network' => isset( $v['Network'] ) ? wp_strip_all_tags( $v['Network'] ) : 'N/A', |
| 646 |
'plugin_uri' => isset( $v['PluginURI'] ) ? wp_strip_all_tags( $v['PluginURI'] ) : 'N/A', |
| 647 |
]; |
| 648 |
if ( in_array( $k, $active_plugins_keys ) ) { |
| 649 |
unset( $plugins[ $k ] ); // Remove active plugins from list so we can show active and inactive separately0 |
| 650 |
$active_plugins[ $k ] = $formatted; |
| 651 |
} else { |
| 652 |
$plugins[ $k ] = $formatted; |
| 653 |
} |
| 654 |
} |
| 655 |
|
| 656 |
return [ |
| 657 |
'active_plugins' => $active_plugins, |
| 658 |
'inactive_plugins' => $plugins, |
| 659 |
]; |
| 660 |
} |
| 661 |
|
| 662 |
/** |
| 663 |
* Get user totals based on user role. |
| 664 |
* |
| 665 |
* @return array |
| 666 |
*/ |
| 667 |
public function __get_user_counts() { |
| 668 |
$user_count = []; |
| 669 |
$user_count_data = count_users(); |
| 670 |
$user_count['total'] = $user_count_data['total_users']; |
| 671 |
// Get user count based on user role. |
| 672 |
foreach ( $user_count_data['avail_roles'] as $role => $count ) { |
| 673 |
$user_count[ $role ] = $count; |
| 674 |
} |
| 675 |
|
| 676 |
return $user_count; |
| 677 |
} |
| 678 |
|
| 679 |
/** |
| 680 |
* Add weekly cron schedule |
| 681 |
* |
| 682 |
* @param array $schedules Cron Schedules. |
| 683 |
* |
| 684 |
* @return array |
| 685 |
*/ |
| 686 |
public function add_weekly_schedule( $schedules ) { |
| 687 |
$schedules['weekly'] = [ |
| 688 |
'interval' => DAY_IN_SECONDS * 7, |
| 689 |
'display' => __( 'Once Weekly', 'disco' ), |
| 690 |
]; |
| 691 |
|
| 692 |
return $schedules; |
| 693 |
} |
| 694 |
|
| 695 |
/** |
| 696 |
* Plugin activation hook |
| 697 |
* |
| 698 |
* @return void |
| 699 |
*/ |
| 700 |
public function activate_plugin() { |
| 701 |
$allowed = get_option( $this->client->getSlug() . '_allow_tracking', 'no' ); |
| 702 |
// if it wasn't allowed before, do nothing. |
| 703 |
if ( 'yes' !== $allowed ) { |
| 704 |
return; |
| 705 |
} |
| 706 |
// re-schedule and delete the last sent time so we could force send again. |
| 707 |
wp_schedule_event( time(), 'weekly', $this->client->getSlug() . '_tracker_send_event' ); |
| 708 |
delete_option( $this->client->getSlug() . '_tracking_last_send' ); |
| 709 |
$this->send_tracking_data( true ); |
| 710 |
} |
| 711 |
|
| 712 |
/** |
| 713 |
* Clear our options upon deactivation |
| 714 |
* |
| 715 |
* @return void |
| 716 |
*/ |
| 717 |
public function deactivation_cleanup() { |
| 718 |
$this->__clear_schedule_event(); |
| 719 |
if ( 'theme' == $this->client->getType() ) { |
| 720 |
delete_option( $this->client->getSlug() . '_tracking_last_send' ); |
| 721 |
delete_option( $this->client->getSlug() . '_allow_tracking' ); |
| 722 |
} |
| 723 |
delete_option( $this->client->getSlug() . '_tracking_notice' ); |
| 724 |
} |
| 725 |
|
| 726 |
/** |
| 727 |
* Hook into action links and modify the deactivate link |
| 728 |
* |
| 729 |
* @param array $links Plugin Action Links. |
| 730 |
* |
| 731 |
* @return array |
| 732 |
*/ |
| 733 |
public function plugin_action_links( $links ) { |
| 734 |
|
| 735 |
if ( array_key_exists( 'deactivate', $links ) ) { |
| 736 |
$links['deactivate'] = str_replace( '<a', '<a class="' . $this->client->getSlug() . '-deactivate-link"', $links['deactivate'] ); |
| 737 |
} |
| 738 |
|
| 739 |
return $links; |
| 740 |
} |
| 741 |
|
| 742 |
/** |
| 743 |
* Deactivation reasons |
| 744 |
* @return array |
| 745 |
*/ |
| 746 |
private function __get_uninstall_reasons() { |
| 747 |
|
| 748 |
$reasons = [ |
| 749 |
[ |
| 750 |
'id' => 'could-not-understand', |
| 751 |
'text' => esc_html__( 'I couldn\'t understand how to make it work', 'disco' ), |
| 752 |
'type' => 'textarea', |
| 753 |
'placeholder' => esc_html__( 'Would you like us to assist you?', 'disco' ), |
| 754 |
], |
| 755 |
[ |
| 756 |
'id' => 'found-better-plugin', |
| 757 |
'text' => esc_html__( 'I found a better plugin', 'disco' ), |
| 758 |
'type' => 'text', |
| 759 |
'placeholder' => esc_html__( 'Which plugin?', 'disco' ), |
| 760 |
], |
| 761 |
[ |
| 762 |
'id' => 'not-have-that-feature', |
| 763 |
'text' => esc_html__( 'The plugin is great, but I need specific feature that you don\'t support', 'disco' ), |
| 764 |
'type' => 'textarea', |
| 765 |
'placeholder' => esc_html__( 'Could you tell us more about that feature?', 'disco' ), |
| 766 |
], |
| 767 |
[ |
| 768 |
'id' => 'is-not-working', |
| 769 |
'text' => esc_html__( 'The plugin is not working', 'disco' ), |
| 770 |
'type' => 'textarea', |
| 771 |
'placeholder' => esc_html__( 'Could you tell us a bit more whats not working?', 'disco' ), |
| 772 |
], |
| 773 |
[ |
| 774 |
'id' => 'looking-for-other', |
| 775 |
'text' => esc_html__( 'It\'s not what I was looking for', 'disco' ), |
| 776 |
'type' => '', |
| 777 |
'placeholder' => '', |
| 778 |
], |
| 779 |
[ |
| 780 |
'id' => 'did-not-work-as-expected', |
| 781 |
'text' => esc_html__( 'The plugin didn\'t work as expected', 'disco' ), |
| 782 |
'type' => 'textarea', |
| 783 |
'placeholder' => esc_html__( 'What did you expect?', 'disco' ), |
| 784 |
], |
| 785 |
[ |
| 786 |
'id' => 'debugging', |
| 787 |
'text' => esc_html__( 'Temporary deactivation for debugging', 'disco' ), |
| 788 |
'type' => '', |
| 789 |
'placeholder' => '', |
| 790 |
], |
| 791 |
[ |
| 792 |
'id' => 'other', |
| 793 |
'text' => esc_html__( 'Other', 'disco' ), |
| 794 |
'type' => 'textarea', |
| 795 |
'placeholder' => esc_html__( 'Could you tell us a bit more?', 'disco' ), |
| 796 |
], |
| 797 |
]; |
| 798 |
$extra = apply_filters( $this->client->getSlug() . '_extra_uninstall_reasons', [], $reasons ); |
| 799 |
if ( is_array( $extra ) && ! empty( $extra ) ) { |
| 800 |
// extract the last (other) reason and add after extras. |
| 801 |
$other = array_pop( $reasons ); |
| 802 |
$reasons = array_merge( $reasons, $extra, [ $other ] ); |
| 803 |
} |
| 804 |
return $reasons; |
| 805 |
} |
| 806 |
|
| 807 |
/** |
| 808 |
* Plugin deactivation uninstall reason submission |
| 809 |
* |
| 810 |
* @return void |
| 811 |
*/ |
| 812 |
public function uninstall_reason_submission() { |
| 813 |
check_ajax_referer( $this->client->getSlug() . '_insight_action' ); |
| 814 |
if ( ! isset( $_POST['reason_id'] ) ) { |
| 815 |
wp_send_json_error( esc_html__( 'Invalid Request', 'disco' ) ); |
| 816 |
wp_die(); |
| 817 |
} |
| 818 |
$current_user = wp_get_current_user(); |
| 819 |
global $wpdb; |
| 820 |
// @TODO remove deprecated data after server update |
| 821 |
$data = [ |
| 822 |
'hash' => $this->client->getHash(), |
| 823 |
'reason_id' => isset( $_REQUEST['reason_id'] ) && ! empty( $_REQUEST['reason_id'] ) ? sanitize_text_field( $_REQUEST['reason_id'] ) : '', |
| 824 |
'reason_info' => isset( $_REQUEST['reason_info'] ) ? trim( sanitize_textarea_field( $_REQUEST['reason_info'] ) ) : '', |
| 825 |
'plugin' => $this->client->getName(), |
| 826 |
'site' => $this->__get_site_name(), |
| 827 |
'url' => esc_url( home_url() ), |
| 828 |
'admin_email' => get_option( 'admin_email' ), |
| 829 |
'user_email' => $current_user->user_email, |
| 830 |
'user_name' => $current_user->display_name, |
| 831 |
// deprecated. |
| 832 |
'first_name' => ( ! empty( $current_user->first_name ) ) ? $current_user->first_name : $current_user->display_name, |
| 833 |
'last_name' => $current_user->last_name, |
| 834 |
'server' => $this->__get_server_info(), |
| 835 |
'software' => isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( $_SERVER['SERVER_SOFTWARE'] ) : 'Generic', // deprecated, using $data['server'] for wp info. |
| 836 |
'php_version' => phpversion(), // deprecated, using $data['server'] for wp info. |
| 837 |
'mysql_version' => $wpdb->db_version(), // deprecated, using $data['server'] for wp info. |
| 838 |
'wp' => $this->__get_wp_info(), |
| 839 |
'wp_version' => get_bloginfo( 'version' ), // deprecated, using $data['wp'] for wp info. |
| 840 |
'locale' => get_locale(), // deprecated, using $data['wp'] for wp info. |
| 841 |
'multisite' => is_multisite() ? 'Yes' : 'No', // deprecated, using $data['wp'] for wp info. |
| 842 |
'ip_address' => $this->__get_user_ip_address(), |
| 843 |
'version' => $this->client->getProjectVersion(), |
| 844 |
]; |
| 845 |
// Add extra data. |
| 846 |
$extra = $this->get_extra_data(); |
| 847 |
if ( ! empty( $extra ) ) { |
| 848 |
$data['extra'] = $extra; |
| 849 |
} |
| 850 |
$this->client->send_request( $data, 'reason' ); |
| 851 |
wp_send_json_success(); |
| 852 |
wp_die(); |
| 853 |
} |
| 854 |
|
| 855 |
/** |
| 856 |
* Handle Support Ticket Submission |
| 857 |
* @return void |
| 858 |
*/ |
| 859 |
public function support_ticket_submission() { |
| 860 |
check_ajax_referer( $this->client->getSlug() . '_insight_action' ); |
| 861 |
if ( empty( $this->ticketTemplate ) || empty( $this->ticketRecipient ) || empty( $this->supportURL ) ) { |
| 862 |
wp_send_json_error( |
| 863 |
sprintf( |
| 864 |
'<p class="mui-error">%s<br>%s</p>', |
| 865 |
esc_html__( 'Something Went Wrong.', 'disco' ), |
| 866 |
esc_html__( 'Please try again after sometime.', 'disco' ) |
| 867 |
) |
| 868 |
); |
| 869 |
wp_die(); |
| 870 |
} |
| 871 |
if ( |
| 872 |
isset( $_REQUEST['name'], $_REQUEST['email'], $_REQUEST['subject'], $_REQUEST['website'], $_REQUEST['message'] ) && |
| 873 |
( |
| 874 |
! empty( sanitize_text_field( $_REQUEST['name'] ) ) && |
| 875 |
! empty( sanitize_email( $_REQUEST['email'] ) ) && |
| 876 |
! empty( sanitize_text_field( $_REQUEST['subject'] ) ) && |
| 877 |
! empty( sanitize_text_field( $_REQUEST['website'] ) ) && |
| 878 |
! empty( sanitize_text_field( $_REQUEST['message'] ) ) |
| 879 |
) |
| 880 |
) { |
| 881 |
$headers = [ |
| 882 |
'Content-Type: text/html; charset=UTF-8', |
| 883 |
sprintf( |
| 884 |
'From: %s <%s>', |
| 885 |
sanitize_text_field( $_REQUEST['name'] ), |
| 886 |
sanitize_email( $_REQUEST['email'] ) |
| 887 |
), |
| 888 |
sprintf( |
| 889 |
'Reply-To: %s <%s>', |
| 890 |
sanitize_text_field( $_REQUEST['name'] ), |
| 891 |
sanitize_text_field( $_REQUEST['email'] ) |
| 892 |
), |
| 893 |
]; |
| 894 |
|
| 895 |
foreach ( $_REQUEST as $k => $v ) { |
| 896 |
$sanitizer = 'sanitize_text_field'; |
| 897 |
if ( 'email' == $k ) { |
| 898 |
$sanitizer = 'sanitize_email'; |
| 899 |
} |
| 900 |
if ( 'website' == $k ) { |
| 901 |
$sanitizer = 'esc_url'; |
| 902 |
} |
| 903 |
$v = call_user_func_array( $sanitizer, [ $v ] ); |
| 904 |
$_REQUEST[ $k ] = $v; // phpcs: sanitize ok. |
| 905 |
$k = '__' . strtoupper( $k ) . '__'; |
| 906 |
$this->ticketTemplate = str_replace( [ $k ], [ $v ], $this->ticketTemplate ); |
| 907 |
} |
| 908 |
$projectSlug = $this->client->getSlug(); |
| 909 |
$isSent = wp_mail( $this->ticketRecipient, sanitize_text_field( $_REQUEST['subject'] ), sprintf( '<div>%s</div>', $this->ticketTemplate ), $headers );// phpcs:ignore WordPressVIPMinimum.Functions.RestrictedFunctions.wp_mail_wp_mail |
| 910 |
if ( $isSent ) { |
| 911 |
/** |
| 912 |
* Set Ajax Success Response for Support Ticket Submission |
| 913 |
* @param string $supportResponse |
| 914 |
* @param array $_REQUEST |
| 915 |
*/ |
| 916 |
$supportResponse = apply_filters( "WebAppick_{$projectSlug}_Support_Request_Ajax_Success_Response" , false, $_REQUEST ); |
| 917 |
if ( false !== $supportResponse ) { |
| 918 |
$this->supportResponse = $supportResponse; |
| 919 |
} else { |
| 920 |
$this->supportResponse = sprintf( |
| 921 |
'<h3>%s</h3>', |
| 922 |
esc_html__( 'Thank you -- Support Ticket Submitted.', 'disco' ) |
| 923 |
); |
| 924 |
} |
| 925 |
wp_send_json_success( $this->supportResponse ); |
| 926 |
wp_die(); |
| 927 |
} else { |
| 928 |
/** |
| 929 |
* Set Support Ticket Ajax Error Response. |
| 930 |
* @param string $supportErrorResponse |
| 931 |
* @param array $_REQUEST |
| 932 |
*/ |
| 933 |
$supportErrorResponse = apply_filters( "WebAppick_{$projectSlug}_Support_Request_Ajax_Error_Response" , false, $_REQUEST ); |
| 934 |
if ( false !== $supportErrorResponse ) { |
| 935 |
$this->supportErrorResponse = $supportErrorResponse; |
| 936 |
} else { |
| 937 |
$this->supportErrorResponse = sprintf( |
| 938 |
'<div class="mui-error"><p>%s</p></div>', |
| 939 |
esc_html__( 'Something Went Wrong. Please Try Again After Sometime.', 'disco' ) |
| 940 |
); |
| 941 |
} |
| 942 |
wp_send_json_error( $this->supportErrorResponse ); |
| 943 |
} |
| 944 |
} else { |
| 945 |
wp_send_json_error( sprintf( '<p class="mui-error">%s</p>', esc_html__( 'Missing Required Fields.', 'disco' ) ) ); |
| 946 |
} |
| 947 |
wp_die(); |
| 948 |
} |
| 949 |
|
| 950 |
/** |
| 951 |
* Handle the plugin deactivation feedback |
| 952 |
* |
| 953 |
* @return void |
| 954 |
*/ |
| 955 |
public function deactivate_scripts() { |
| 956 |
global $pagenow; |
| 957 |
if ( 'plugins.php' !== $pagenow ) { |
| 958 |
return; |
| 959 |
} |
| 960 |
$reasons = $this->__get_uninstall_reasons(); |
| 961 |
$admin_user = $this->__get_admin(); |
| 962 |
$displayName = ( ! empty( $admin_user->first_name ) && ! empty( $admin_user->last_name ) ) ? $admin_user->first_name . ' ' . $admin_user->last_name : $admin_user->display_name; |
| 963 |
$showSupportTicket = ( ! empty( $this->ticketTemplate ) && ! empty( $this->ticketRecipient ) && ! empty( $this->supportURL ) ); |
| 964 |
?> |
| 965 |
<div class="wapk-dr-modal" id="<?php echo esc_attr( $this->client->getSlug() ); ?>-wapk-dr-modal" aria-label="<?php /* translators: 1: Plugin Name */ printf( esc_attr__( '“%s” Uninstall Confirmation', 'disco' ), esc_attr( $this->client->getName() ) ); ?>" role="dialog" aria-modal="true"> |
| 966 |
<?php if ( $showSupportTicket ) { ?> |
| 967 |
<div class="disco-deactivation-modal wapk-dr-modal-wrap support" style="display: none;"> |
| 968 |
<div class="wapk-dr-modal-header"> |
| 969 |
<h3><?php esc_html_e( 'Submit Support Ticket.', 'disco' ); ?></h3> |
| 970 |
<a href="javascript:void 0;" class="wapk-dr-modal-close" aria-label="<?php esc_attr_e( 'Close', 'disco' ); ?>"> |
| 971 |
<!--suppress HtmlUnknownAttribute --> |
| 972 |
<svg class="" focusable="false" viewBox="0 0 24 24" aria-hidden="true" role="presentation"> |
| 973 |
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path> |
| 974 |
</svg> |
| 975 |
</a> |
| 976 |
</div> |
| 977 |
<div class="wapk-dr-modal-body"> |
| 978 |
<div class="wapk-row mui col-2 col-left"> |
| 979 |
<label for="wapk-support-name" class="<?php echo ! empty( $displayName ) ? 'shrink' : ''; ?>"><?php esc_html_e( 'Name', 'disco' ); ?></label> |
| 980 |
<div class="wapk-form-control"> |
| 981 |
<input type="text" name="name" id="wapk-support-name" value="<?php echo esc_attr( $displayName ); ?>" required> |
| 982 |
</div> |
| 983 |
</div> |
| 984 |
<div class="wapk-row mui col-2 col-right"> |
| 985 |
<label for="wapk-support-email" class="shrink"><?php esc_html_e( 'Email', 'disco' ); ?></label> |
| 986 |
<div class="wapk-form-control"> |
| 987 |
<input type="email" name="email" id="wapk-support-email" value="<?php echo esc_attr( $admin_user->user_email ); ?>" required> |
| 988 |
</div> |
| 989 |
</div> |
| 990 |
<div class="clear"></div> |
| 991 |
<div class="wapk-row mui col-2 col-left"> |
| 992 |
<label for="wapk-support-subject"><?php esc_html_e( 'Subject', 'disco' ); ?></label> |
| 993 |
<div class="wapk-form-control"> |
| 994 |
<input type="text" name="subject" id="wapk-support-subject" required> |
| 995 |
</div> |
| 996 |
</div> |
| 997 |
<div class="wapk-row mui col-2 col-right"> |
| 998 |
<label for="wapk-support-website" class="shrink"><?php esc_html_e( 'Website', 'disco' ); ?></label> |
| 999 |
<div class="wapk-form-control"> |
| 1000 |
<input type="url" name="website" id="wapk-support-website" value="<?php echo esc_url( site_url() ); ?>" required> |
| 1001 |
</div> |
| 1002 |
</div> |
| 1003 |
<div class="clear"></div> |
| 1004 |
<div class="wapk-row mui"> |
| 1005 |
<label for="wapk-support-message"><?php esc_html_e( 'Message', 'disco' ); ?></label> |
| 1006 |
<div class="wapk-form-control"> |
| 1007 |
<textarea id="wapk-support-message" name='message' rows="11" required></textarea> |
| 1008 |
</div> |
| 1009 |
</div> |
| 1010 |
<div class="response"> |
| 1011 |
<div class="wrapper"></div> |
| 1012 |
</div> |
| 1013 |
</div> |
| 1014 |
<div class="wapk-dr-modal-footer"> |
| 1015 |
<button class="disco-notice-primary-button send-ticket"><?php esc_html_e( 'Send Message', 'disco' ); ?></button> |
| 1016 |
<button class="disco-notice-secondary-button close-ticket"><?php esc_html_e( 'Cancel', 'disco' ); ?></button> |
| 1017 |
</div> |
| 1018 |
</div> |
| 1019 |
<?php } ?> |
| 1020 |
<div class="disco-deactivation-modal wapk-dr-modal-wrap reason"> |
| 1021 |
<div class="wapk-dr-modal-header"> |
| 1022 |
<h3><?php esc_html_e( 'If you have a moment, please let us know why you are deactivating:', 'disco' ); ?></h3> |
| 1023 |
<a href="javascript:void 0;" class="wapk-dr-modal-close" aria-label="<?php esc_attr_e( 'Close', 'disco' ); ?>"> |
| 1024 |
<!--suppress HtmlUnknownAttribute --> |
| 1025 |
<svg class="" focusable="false" viewBox="0 0 24 24" aria-hidden="true" role="presentation"> |
| 1026 |
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path> |
| 1027 |
</svg> |
| 1028 |
</a> |
| 1029 |
</div> |
| 1030 |
<div class="wapk-dr-modal-body"> |
| 1031 |
<ul class="reasons"> |
| 1032 |
<?php foreach ( $reasons as $reason ) { ?> |
| 1033 |
<li data-type="<?php echo esc_attr( $reason['type'] ); ?>" data-placeholder="<?php echo esc_attr( $reason['placeholder'] ); ?>"> |
| 1034 |
<label><input type="radio" name="selected-reason" value="<?php echo esc_attr( $reason['id'] ); ?>"> <?php echo esc_html( $reason['text'] ); ?></label> |
| 1035 |
</li> |
| 1036 |
<?php } ?> |
| 1037 |
</ul> |
| 1038 |
<div class="response" style="<?php echo ( $showSupportTicket ) ? 'display: block;' : ''; ?>"> |
| 1039 |
<div class="disco-deactivation-modal wrapper"> |
| 1040 |
<?php if ( $showSupportTicket ) { ?> |
| 1041 |
<p><?php esc_html_e( 'In trouble? Please submit a support request.', 'disco' ); ?></p> |
| 1042 |
<p> |
| 1043 |
<a href="#" class="disco-notice-secondary-button not-interested"><?php esc_html_e( 'Not Interested', 'disco' ); ?></a> |
| 1044 |
<button class="disco-notice-primary-button open-ticket-form"><?php esc_html_e( 'Open Support Ticket', 'disco' ); ?></button> |
| 1045 |
</p> |
| 1046 |
<?php } ?> |
| 1047 |
</div> |
| 1048 |
</div> |
| 1049 |
</div> |
| 1050 |
<div class="wapk-dr-modal-footer"> |
| 1051 |
<a style="background:transparent !important;" href="#" class="button button-link dont-bother-me disabled"><?php esc_html_e( 'I rather wouldn\'t say', 'disco' ); ?></a> |
| 1052 |
<button class="disco-notice-secondary-button deactivate"><?php esc_html_e( 'Submit & Deactivate', 'disco' ); ?></button> |
| 1053 |
<button class="disco-notice-primary-button modal-close"><?php esc_html_e( 'Cancel', 'disco' ); ?></button> |
| 1054 |
</div> |
| 1055 |
</div> |
| 1056 |
</div> |
| 1057 |
<!--suppress CssUnusedSymbol, CssInvalidPseudoSelector, CssFloatPxLength --> |
| 1058 |
<style type="text/css"> |
| 1059 |
.wapk-dr-modal, .wapk-dr-modal * { box-sizing: border-box; } |
| 1060 |
.wapk-dr-modal { position: fixed; z-index: 99999; top: 0; right: 0; bottom: 0; left: 0; background: rgba(0, 0, 0, 0.5); display: none; } |
| 1061 |
.wapk-dr-modal.modal-active { display: block; } |
| 1062 |
.wapk-dr-modal strong, .wapk-dr-modal b { font-weight: bold; } |
| 1063 |
.wapk-dr-modal-wrap { width: 475px; position: relative; margin: 10% auto; background: #fff; } |
| 1064 |
.wapk-dr-modal-wrap { position: absolute; display: block; top: 0; left: 0; right: 0; /*bottom: 0;*/ z-index: 99; } |
| 1065 |
.wapk-dr-modal-wrap.support { z-index: 999; margin: 6% auto; } |
| 1066 |
.wapk-dr-modal-wrap .response { position: absolute; display: none; background: rgba(0, 150, 136, 0.68); top: 0; left: 0; right: 0; bottom: 0; overflow: hidden; } |
| 1067 |
.wapk-dr-modal .response.show { display: block; } |
| 1068 |
.wapk-dr-modal-wrap .response .wrapper { display: flex; align-items: center; justify-content: center; width: calc(100% - 40px); height: calc(100% - 40px); flex-flow: column; padding: 40px 40px; margin: 20px 20px; text-align: center; background: #FFF; } |
| 1069 |
.wapk-dr-modal .reason .response .wrapper { width: calc(100% - 80px); height: calc(100% - 80px); flex-flow: column; padding: 40px 40px; margin: 40px; } |
| 1070 |
.wapk-dr-modal .button .dashicons { margin: 4px 0; } |
| 1071 |
.wapk-dr-modal-header { border-bottom: 1px solid #eee; padding: 8px 40px 8px 20px; position: relative; display: block; width: 100%; float: left; } |
| 1072 |
.wapk-dr-modal-header h3 { line-height: 150%; margin: 0; } |
| 1073 |
.wapk-dr-modal-close { position: absolute; top: 50%; right: 10px; transform: translateY(-50%); width: 20px; height: 20px; line-height: 0; } |
| 1074 |
.wapk-dr-modal-close svg { font-size: 20px; display: inline-block; width: 1em; height: 1em; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } |
| 1075 |
.wapk-dr-modal-body { padding: 5px 20px 20px 20px; position: relative; display: block; width: 100%; float: left; box-sizing: border-box; } |
| 1076 |
.wapk-dr-modal-body .reason-input { margin-top: 5px; margin-left: 20px; } |
| 1077 |
.wapk-dr-modal-footer { border-top: 1px solid #eee; padding: 12px 20px; text-align: right; position: relative; display: block; width: 100%; float: left; } |
| 1078 |
.wapk-dr-modal-footer a, .wapk-dr-modal-footer button { vertical-align: middle; } |
| 1079 |
.support .wapk-dr-modal-footer { text-align: left; } |
| 1080 |
.support .wapk-dr-modal-footer button { float: right; margin-left: 10px; } |
| 1081 |
.wapk-dr-modal .wapk-row { position: relative; width: 100%; display: block; box-sizing: border-box; float: left; margin: 4px auto; } |
| 1082 |
.mui { border: 0; margin: 0; display: inline-flex; padding: 0; min-width: 0; flex-direction: column; vertical-align: top; } |
| 1083 |
.wapk-dr-modal .wapk-row.col-2 { width: calc(50% - 16px); } |
| 1084 |
.wapk-dr-modal .wapk-row.col-3 { width: calc(calc(100% / 3) - 16px); } |
| 1085 |
.wapk-dr-modal .wapk-row.col-left { margin-right: 8px; } |
| 1086 |
.wapk-dr-modal .wapk-row.col-center { margin-left: 8px; margin-right: 8px; } |
| 1087 |
.wapk-dr-modal .wapk-row.col-right { margin-left: 8px; } |
| 1088 |
.wapk-dr-modal .mui .wapk-form-control { cursor: text; display: inline-flex; position: relative; font-size: 1rem; box-sizing: border-box; align-items: center; line-height: 1.1875em; width: 100%; } |
| 1089 |
.wapk-dr-modal .mui label { color: rgba(0, 0, 0, 0.54); padding: 0; font-size: 1rem; font-weight: 400; line-height: 1; letter-spacing: 0.00938em; display: block; transform-origin: top left; top: 0; left: 0; position: absolute; transform: translate(0, 24px) scale(1); transition: color 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms, transform 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; } |
| 1090 |
.wapk-dr-modal .mui label.focused { color: #007cba; } |
| 1091 |
p:not(.helper-text).mui-error, div:not(.helper-text).mui-error, .wapk-dr-modal .mui label.mui-error { color: #f44336; } |
| 1092 |
p:not(.helper-text).mui-error, div:not(.helper-text).mui-error { padding: 5px 10px; border: 1px solid #f44336; font-weight: bold; } |
| 1093 |
.wapk-dr-modal .mui label.shrink { transform: translate(0, 1.5px) scale(0.75); transform-origin: top left; } |
| 1094 |
.wapk-dr-modal .mui label + .wapk-form-control { margin-top: 16px; } |
| 1095 |
.wapk-dr-modal .mui .wapk-form-control:before { left: 0; right: 0; bottom: 0; content: "\00a0"; position: absolute; transition: border-bottom-color 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; border-bottom: 1px solid rgba(0, 0, 0, 0.42); pointer-events: none; } |
| 1096 |
.wapk-dr-modal .mui .wapk-form-control:hover:not(.disabled):before { border-bottom: 2px solid rgba(0, 0, 0, 0.87); } |
| 1097 |
.wapk-dr-modal .mui .wapk-form-control:after { left: 0; right: 0; bottom: 0; content: ""; position: absolute; transform: scaleX(0); transition: transform 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms; border-bottom: 2px solid #007cba; pointer-events: none; } |
| 1098 |
.wapk-dr-modal .mui .wapk-form-control.focused:after { transform: scaleX(1); } |
| 1099 |
.wapk-dr-modal .mui .wapk-form-control.mui-error:after { transform: scaleX(1); border-bottom-color: #f44336; } |
| 1100 |
.wapk-dr-modal .mui .wapk-form-control input, |
| 1101 |
.wapk-dr-modal .mui .wapk-form-control textarea { font: inherit; color: currentColor; width: 100%; border: 0; height: 1.1875em; min-height: auto; margin: 0; display: block; padding: 6px 0 7px; min-width: 0; background: none; box-sizing: content-box; -webkit-tap-highlight-color: transparent; } |
| 1102 |
.wapk-dr-modal .mui .wapk-form-control input { animation-name: mui-keyframes-auto-fill-cancel; } |
| 1103 |
.wapk-dr-modal .mui .wapk-form-control input:-moz-autofill, |
| 1104 |
.wapk-dr-modal .mui .wapk-form-control input:-webkit-autofill { animation-name: mui-keyframes-auto-fill; animation-duration: 5000s; } |
| 1105 |
@-webkit-keyframes mui-keyframes-auto-fill {} |
| 1106 |
@-webkit-keyframes mui-keyframes-auto-fill-cancel {} |
| 1107 |
.wapk-dr-modal .mui .wapk-form-control textarea { height: auto; resize: none; padding: 0; } |
| 1108 |
.wapk-dr-modal .mui .wapk-form-control input::-webkit-search-decoration, |
| 1109 |
.wapk-dr-modal .mui .wapk-form-control textarea::-webkit-search-decoration { -webkit-appearance: none; } |
| 1110 |
.wapk-dr-modal .mui .wapk-form-control input::-webkit-input-placeholder, |
| 1111 |
.wapk-dr-modal .mui .wapk-form-control textarea::-webkit-input-placeholder { color: currentColor; opacity: 0.42; transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; } |
| 1112 |
.wapk-dr-modal .mui .wapk-form-control input::-moz-placeholder, |
| 1113 |
.wapk-dr-modal .mui .wapk-form-control textarea::-moz-placeholder { color: currentColor; opacity: 0.42; transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; } |
| 1114 |
.wapk-dr-modal .mui .wapk-form-control input:-ms-input-placeholder, |
| 1115 |
.wapk-dr-modal .mui .wapk-form-control textarea:-ms-input-placeholder { color: currentColor; opacity: 0.42; transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; } |
| 1116 |
.wapk-dr-modal .mui .wapk-form-control input::-ms-input-placeholder, |
| 1117 |
.wapk-dr-modal .mui .wapk-form-control textarea::-ms-input-placeholder { color: currentColor; opacity: 0.42; transition: opacity 200ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; } |
| 1118 |
.wapk-dr-modal .mui .wapk-form-control input:focus, |
| 1119 |
.wapk-dr-modal .mui .wapk-form-control input:invalid, |
| 1120 |
.wapk-dr-modal .mui .wapk-form-control textarea:focus, |
| 1121 |
.wapk-dr-modal .mui .wapk-form-control textarea:invalid { outline: 0; box-shadow: none; } |
| 1122 |
.wapk-dr-modal .mui .helper-text { color: rgba(0, 0, 0, 0.54); margin: 8px 0 0 0; font-size: 0.75rem; min-height: 1em; text-align: left; font-weight: 400; line-height: 1em; letter-spacing: 0.03333em; } |
| 1123 |
.wapk-dr-modal .mui .helper-text.contained { margin: 8px 14px 0; } |
| 1124 |
.wapk-dr-modal .mui .helper-text.mui-error { color: #f44336; } |
| 1125 |
.wapk-dr-modal .button.disabled, .wapk-dr-modal button.disabled { cursor: not-allowed !important; } |
| 1126 |
/*.wapk-dr-modal .wapk-row input, .wapk-dr-modal .wapk-row textarea { width: calc( 100% - 10px ); margin: 0 5px; display: block; vertical-align: middle; box-sizing: border-box; float: left; }*/ |
| 1127 |
</style> |
| 1128 |
<!--suppress ES6ConvertVarToLetConst, JSUnresolvedVariable --> |
| 1129 |
<script type="text/javascript"> |
| 1130 |
(function ($) { |
| 1131 |
$(function () { |
| 1132 |
/** |
| 1133 |
* Ajax Helper For Submitting Deactivation Reasons |
| 1134 |
* @param {Object} data |
| 1135 |
* @param {*|jQuery|HTMLElement} buttonElem |
| 1136 |
* @param {String|Function} cb |
| 1137 |
* @returns {*|jQuery} |
| 1138 |
* @private |
| 1139 |
*/ |
| 1140 |
function _ajax(data, buttonElem, cb) { |
| 1141 |
if (buttonElem.hasClass('disabled')) return; |
| 1142 |
buttonElem.attr('data-label', buttonElem.text()); |
| 1143 |
return $.ajax({ |
| 1144 |
url: ajaxurl, |
| 1145 |
type: 'POST', |
| 1146 |
data: $.fn.extend( {}, { |
| 1147 |
action: '<?php echo esc_attr( $this->client->getSlug() ); ?>_submit-uninstall-reason', |
| 1148 |
_wpnonce: '<?php echo esc_attr( wp_create_nonce( $this->client->getSlug() . '_insight_action' ) ); ?>' |
| 1149 |
}, data ), // add default action if action is empty. |
| 1150 |
beforeSend: function () { |
| 1151 |
buttonElem.addClass("disabled"); |
| 1152 |
buttonElem.text('<?php esc_html_e( 'Processing...', 'disco' ); ?>'); |
| 1153 |
}, |
| 1154 |
complete: function (event, xhr, options) { |
| 1155 |
if ('string' === typeof cb) { |
| 1156 |
window.location.href = cb; |
| 1157 |
} else if ('function' === typeof cb) { |
| 1158 |
cb({event: event, xhr: xhr, options: options}); |
| 1159 |
} |
| 1160 |
} |
| 1161 |
}); |
| 1162 |
} |
| 1163 |
// Variables. |
| 1164 |
var modal = $('#<?php echo esc_attr( $this->client->getSlug() ); ?>-wapk-dr-modal'), |
| 1165 |
deactivateLink = '', |
| 1166 |
reason = modal.find('.reason'), |
| 1167 |
support = modal.find('.support'), |
| 1168 |
supportResponse = support.find('.response'), |
| 1169 |
reasonResponse = reason.find('.response'), |
| 1170 |
mui = $('.mui input, .mui textarea, .mui select'), |
| 1171 |
// sendButton = modal.find('.send-ticket'), |
| 1172 |
validMessage = false, |
| 1173 |
preventDefault = function ( e ) { e && e.preventDefault() }, |
| 1174 |
responseButtons = modal.find('.reason .wapk-dr-modal-footer .button'), |
| 1175 |
supportURL = '<?php echo esc_url( $this->supportURL ); ?>', |
| 1176 |
closeModal = function (e) { |
| 1177 |
preventDefault(e); |
| 1178 |
var buttons = modal.find('.button'); |
| 1179 |
modal.removeClass('modal-active'); |
| 1180 |
// modal.find('.wapk-dr-modal-wrap').show(); |
| 1181 |
supportResponse.hide().find('.wrapper').html(''); |
| 1182 |
reasonResponse.show(); |
| 1183 |
support.hide(); |
| 1184 |
// enable buttons and restore original labels |
| 1185 |
buttons.removeClass('disabled'); |
| 1186 |
responseButtons.addClass('disabled'); |
| 1187 |
buttons.each(function () { |
| 1188 |
var self = $(this), label = self.attr('data-label'); |
| 1189 |
if (label) self.text(label); |
| 1190 |
}); |
| 1191 |
modal.find('input[type="radio"]').prop('checked', false ); |
| 1192 |
$('.reason-input').remove(); |
| 1193 |
}, |
| 1194 |
checkMessageValidity = function (e) { |
| 1195 |
// e.target.checkValidity(); |
| 1196 |
var target = e && e.target ? e.target : this; |
| 1197 |
var self = $(this), currentMui = self.closest('.mui'), |
| 1198 |
label = currentMui.find('label'), |
| 1199 |
control = currentMui.find('.wapk-form-control'); |
| 1200 |
if (target.checkValidity()) { |
| 1201 |
if (label.hasClass('mui-error')) label.removeClass('mui-error'); |
| 1202 |
if (control.hasClass('mui-error')) control.removeClass('mui-error'); |
| 1203 |
currentMui.find('p.helper-text').hide().remove(); |
| 1204 |
validMessage = true; |
| 1205 |
} |
| 1206 |
}, |
| 1207 |
resetTicketForm = function( clearValues, clearAll ) { |
| 1208 |
$('p.helper-text.mui-error').remove(); |
| 1209 |
$('.mui-error').removeClass('mui-error'); |
| 1210 |
if( clearValues ) { |
| 1211 |
if( clearAll ) mui.val(''); |
| 1212 |
else modal.find('#wapk-support-message,#wapk-support-subject').val(''); |
| 1213 |
} |
| 1214 |
}; |
| 1215 |
// The MUI |
| 1216 |
{ |
| 1217 |
// any input el except radio, checkbox and select |
| 1218 |
mui |
| 1219 |
.not('select') |
| 1220 |
.not('[type="checkbox"]') |
| 1221 |
.not('[type="radio"]') |
| 1222 |
.on('focus', function () { |
| 1223 |
var self = $(this), currentMui = self.closest('.mui'), |
| 1224 |
label = currentMui.find('label'), |
| 1225 |
control = currentMui.find('.wapk-form-control'); |
| 1226 |
control.addClass('focused'); |
| 1227 |
label.addClass('focused'); |
| 1228 |
label.addClass('shrink'); |
| 1229 |
}) |
| 1230 |
.on('blur', function () { |
| 1231 |
var self = $(this), currentMui = self.closest('.mui'), |
| 1232 |
label = currentMui.find('label'), |
| 1233 |
control = currentMui.find('.wapk-form-control'); |
| 1234 |
control.removeClass('focused'); |
| 1235 |
label.removeClass('focused'); |
| 1236 |
if (self.val() === '') { |
| 1237 |
label.removeClass('shrink'); |
| 1238 |
} |
| 1239 |
}); |
| 1240 |
// any input el in mui |
| 1241 |
mui |
| 1242 |
.on('blur', checkMessageValidity) |
| 1243 |
.on('invalid', function (e) { |
| 1244 |
preventDefault(e); |
| 1245 |
var self = $(this), currentMui = self.closest('.mui'), |
| 1246 |
label = currentMui.find('label'), |
| 1247 |
control = currentMui.find('.wapk-form-control'); |
| 1248 |
currentMui.find('p.helper-text').remove(); |
| 1249 |
validMessage = false; |
| 1250 |
if (!label.hasClass('mui-error')) label.addClass('mui-error'); |
| 1251 |
if (!control.hasClass('mui-error')) control.addClass('mui-error'); |
| 1252 |
control.after('<p class="helper-text mui-error">' + e.target.validationMessage + '</p>'); |
| 1253 |
}); |
| 1254 |
} |
| 1255 |
// the clicker |
| 1256 |
$('#the-list').on('click', 'a.<?php echo esc_attr( $this->client->getSlug() ); ?>-deactivate-link', function (e) { |
| 1257 |
preventDefault(e); |
| 1258 |
modal.addClass('modal-active'); |
| 1259 |
deactivateLink = $(this).attr('href'); |
| 1260 |
modal.find('a.dont-bother-me').attr('href', deactivateLink).css('float', 'left'); |
| 1261 |
}); |
| 1262 |
// The Modal |
| 1263 |
modal |
| 1264 |
.on( 'click', '.not-interested', function(e) { |
| 1265 |
preventDefault(e); |
| 1266 |
$( this ).closest('.response').slideUp( function() { |
| 1267 |
responseButtons.removeClass('disabled'); |
| 1268 |
} ); |
| 1269 |
} ) |
| 1270 |
.on( 'click', '.open-ticket-form', function(e){ |
| 1271 |
preventDefault(e); |
| 1272 |
support.slideDown(); |
| 1273 |
resetTicketForm( true ); |
| 1274 |
} ) |
| 1275 |
.on( 'click', '.close-ticket', function (e) { |
| 1276 |
preventDefault(e); |
| 1277 |
support.slideUp(); |
| 1278 |
//if( ! reasonResponse.is(':visible') ) responseButtons.removeClass('disabled'); |
| 1279 |
} ) |
| 1280 |
.on( 'click', '.modal-close, .wapk-dr-modal-close', closeModal ) |
| 1281 |
.on( 'click', 'input[type="radio"]', function () { |
| 1282 |
modal.find('.reason-input').remove(); |
| 1283 |
var parent = $(this).parents('li:first'), |
| 1284 |
inputType = parent.data('type'), |
| 1285 |
inputPlaceholder = parent.data('placeholder'), |
| 1286 |
reasonInputHtml = '<div class="reason-input">' + (('text' === inputType) ? '<input type="text" size="40" />' : '<textarea rows="5" cols="45"></textarea>') + '</div>'; |
| 1287 |
if (inputType !== '') { |
| 1288 |
parent.append($(reasonInputHtml)); |
| 1289 |
parent.find('input, textarea').attr('placeholder', inputPlaceholder).focus(); |
| 1290 |
} |
| 1291 |
} ) |
| 1292 |
.on( 'click', '.dont-bother-me', function (e) { |
| 1293 |
preventDefault(e); |
| 1294 |
_ajax({ |
| 1295 |
reason_id: 'no-comment', |
| 1296 |
reason_info: 'I rather wouldn\'t say' |
| 1297 |
}, $(this), deactivateLink); |
| 1298 |
} ) |
| 1299 |
.on( 'click', '.deactivate', function (e) { |
| 1300 |
preventDefault(e); |
| 1301 |
var $radio = $('input[type="radio"]:checked', modal), |
| 1302 |
$selected_reason = $radio.parents('li:first'), |
| 1303 |
$input = $selected_reason.find('textarea, input[type="text"]'); |
| 1304 |
_ajax({ |
| 1305 |
reason_id: (0 === $radio.length) ? 'none' : $radio.val(), |
| 1306 |
reason_info: (0 !== $input.length) ? $input.val().trim() : '' |
| 1307 |
}, $(this), deactivateLink); |
| 1308 |
} ) |
| 1309 |
.on( 'click', '.send-ticket', function (e) { |
| 1310 |
preventDefault(e); |
| 1311 |
mui.each(checkMessageValidity); |
| 1312 |
if (!validMessage) return; |
| 1313 |
var buttonElem = $(this), |
| 1314 |
__BTN_TEXT__ = buttonElem.text(), |
| 1315 |
data = {action: '<?php echo esc_attr( $this->client->getSlug() ); ?>_submit-support-ticket',}; |
| 1316 |
mui.each( function () { data[$(this).attr('name')] = $(this).val() } ); |
| 1317 |
_ajax(data, $(this), function (jqXhr) { |
| 1318 |
var response = jqXhr.event.responseJSON; |
| 1319 |
if ( response.hasOwnProperty('data') ) { |
| 1320 |
supportResponse.find('.wrapper').html(response.data); |
| 1321 |
supportResponse.show(); |
| 1322 |
} |
| 1323 |
if( response.success ) { |
| 1324 |
modal.find('#wapk-support-message,#wapk-support-subject').val(''); |
| 1325 |
} else { |
| 1326 |
setTimeout( function() { |
| 1327 |
window.open( supportURL, '_blank' ); |
| 1328 |
// supportResponse.slideUp(); |
| 1329 |
buttonElem.hasClass('disabled') && buttonElem.removeClass('disabled'); |
| 1330 |
}, 5000 ); |
| 1331 |
} |
| 1332 |
buttonElem.text(__BTN_TEXT__); |
| 1333 |
}); |
| 1334 |
}); |
| 1335 |
}); |
| 1336 |
}(jQuery)); |
| 1337 |
</script> |
| 1338 |
<?php |
| 1339 |
} |
| 1340 |
|
| 1341 |
/** |
| 1342 |
* Run after theme deactivated |
| 1343 |
* |
| 1344 |
* @param string $new_name New Theme Name. |
| 1345 |
* @param WP_Theme $new_theme New Theme WP_Theme Object. |
| 1346 |
* @param WP_Theme $old_theme Old Theme WP_Theme Object. |
| 1347 |
* |
| 1348 |
* @return void |
| 1349 |
*/ |
| 1350 |
public function theme_deactivated( $new_name, $new_theme, $old_theme ) { |
| 1351 |
// Make sure this is WebAppick theme. |
| 1352 |
if ( $old_theme->get_template() == $this->client->getSlug() ) { |
| 1353 |
$current_user = wp_get_current_user(); |
| 1354 |
/** @noinspection PhpUndefinedFieldInspection */ |
| 1355 |
$data = [ |
| 1356 |
'hash' => $this->client->getHash(), |
| 1357 |
'reason_id' => 'none', |
| 1358 |
'reason_info' => wp_json_encode( |
| 1359 |
[ |
| 1360 |
'new_theme' => [ |
| 1361 |
'name' => $new_name, |
| 1362 |
'version' => $new_theme->version, |
| 1363 |
'parent_theme' => $new_name->parent_theme, |
| 1364 |
'author' => $new_name->parent_theme, |
| 1365 |
], |
| 1366 |
] |
| 1367 |
), |
| 1368 |
'site' => $this->__get_site_name(), |
| 1369 |
'url' => esc_url( home_url() ), |
| 1370 |
'admin_email' => get_option( 'admin_email' ), |
| 1371 |
'user_email' => $current_user->user_email, |
| 1372 |
'first_name' => $current_user->first_name, |
| 1373 |
'last_name' => $current_user->last_name, |
| 1374 |
'server' => $this->__get_server_info(), |
| 1375 |
'wp' => $this->__get_wp_info(), |
| 1376 |
'ip_address' => $this->__get_user_ip_address(), |
| 1377 |
'version' => $this->client->getProjectVersion(), |
| 1378 |
]; |
| 1379 |
$this->client->send_request( $data, 'reason' ); |
| 1380 |
} |
| 1381 |
} |
| 1382 |
|
| 1383 |
/** |
| 1384 |
* Get user IP Address |
| 1385 |
* @return string |
| 1386 |
*/ |
| 1387 |
private function __get_user_ip_address() { |
| 1388 |
$response = wp_safe_remote_get( 'https://icanhazip.com/' ); |
| 1389 |
if ( is_wp_error( $response ) ) { |
| 1390 |
return ''; |
| 1391 |
} |
| 1392 |
$ip = trim( wp_remote_retrieve_body( $response ) ); |
| 1393 |
if ( ! filter_var( $ip, FILTER_VALIDATE_IP ) ) { |
| 1394 |
return ''; |
| 1395 |
} |
| 1396 |
|
| 1397 |
return $ip; |
| 1398 |
} |
| 1399 |
|
| 1400 |
/** |
| 1401 |
* Get site name |
| 1402 |
* @return string |
| 1403 |
*/ |
| 1404 |
private function __get_site_name() { |
| 1405 |
$site_name = get_bloginfo( 'name' ); |
| 1406 |
if ( empty( $site_name ) ) { |
| 1407 |
$site_name = get_bloginfo( 'description' ); |
| 1408 |
$site_name = wp_trim_words( $site_name, 3, '' ); |
| 1409 |
} |
| 1410 |
if ( empty( $site_name ) ) { |
| 1411 |
$site_name = get_bloginfo( 'url' ); |
| 1412 |
} |
| 1413 |
|
| 1414 |
return $site_name; |
| 1415 |
} |
| 1416 |
} |
| 1417 |
// End of file Insights.php. |
| 1418 |
|