PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 3.6.0
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v3.6.0
3.6.0 3.5.3 3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / vendor / themegrill / themegrill-sdk / src / Modules / UninstallFeedback.php
everest-forms / vendor / themegrill / themegrill-sdk / src / Modules Last commit date
Announcements.php 6 months ago Licenser.php 1 month ago Logger.php 6 months ago Notification.php 6 months ago Rollback.php 6 months ago ScriptLoader.php 6 months ago UninstallFeedback.php 6 months ago Updater.php 1 month ago
UninstallFeedback.php
840 lines
1 <?php
2 /**
3 * The deactivate feedback model class for ThemeGrill SDK
4 *
5 * @package ThemeGrillSDK
6 * @subpackage Feedback
7 * @copyright Copyright (c) 2025, ThemeGrill
8 * @license http://opensource.org/licenses/gpl-3.0.php GNU Public License
9 * @since 1.0.0
10 */
11
12 namespace ThemeGrillSDK\Modules;
13
14 use ThemeGrillSDK\Common\AbstractModule;
15 use ThemeGrillSDK\Loader;
16 use ThemeGrillSDK\Product;
17
18 // Exit if accessed directly.
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit;
21 }
22
23 /**
24 * Uninstall feedback module for ThemeGrill SDK.
25 */
26 class UninstallFeedback extends AbstractModule {
27 /**
28 * How many seconds before the deactivation window is triggered for themes?
29 *
30 * @var int Number of days.
31 */
32 const AUTO_TRIGGER_DEACTIVATE_WINDOW_SECONDS = 3;
33 /**
34 * How many days before the deactivation window pops up again for the theme?
35 *
36 * @var int Number of days.
37 */
38 const PAUSE_DEACTIVATE_WINDOW_DAYS = 100;
39 /**
40 * Where to send the data.
41 *
42 * @var string Endpoint url.
43 */
44 const FEEDBACK_ENDPOINT = 'https://api.themeGrill.com/tracking/uninstall';
45
46 /**
47 * Default options for plugins.
48 *
49 * @var array $options_plugin The main options list for plugins.
50 */
51 private $options_plugin = array(
52 'id3' => array(
53 'id' => 3,
54 'type' => 'text',
55
56 ),
57 'id4' => array(
58 'type' => 'textarea',
59 'id' => 4,
60 ),
61 'id5' => array(
62 'id' => 5,
63 'type' => 'textarea',
64 ),
65 'id6' => array(
66 'type' => 'textarea',
67 'id' => 6,
68 ),
69 );
70 /**
71 * Default options for theme.
72 *
73 * @var array $options_theme The main options list for themes.
74 */
75 private $options_theme = array(
76 'id7' => array(
77 'id' => 7,
78 ),
79 'id8' => array(
80 'type' => 'text',
81 'id' => 8,
82 ),
83 'id9' => array(
84 'id' => 9,
85 'type' => 'text',
86 ),
87 'id10' => array(
88 'title' => '',
89 'id' => 10,
90 ),
91 );
92 /**
93 * Default other option.
94 *
95 * @var array $other The other option
96 */
97 private $other = array(
98 'id999' => array(
99 'id' => 999,
100 'type' => 'textarea',
101 ),
102 );
103
104 /**
105 * Loads the additional resources
106 */
107 public function load_resources() {
108 $screen = get_current_screen();
109
110 if ( ! $screen || ! in_array( $screen->id, array( 'theme-install', 'plugins' ), true ) ) {
111 return;
112 }
113
114 $this->add_feedback_popup_style();
115
116 if ( $this->product->get_type() === 'theme' ) {
117 $this->add_theme_feedback_drawer_js();
118 $this->render_theme_feedback_popup();
119
120 return;
121 }
122 $this->add_plugin_feedback_popup_js();
123 $this->render_plugin_feedback_popup();
124 }
125
126 /**
127 * Render theme feedback drawer.
128 */
129 private function render_theme_feedback_popup() {
130 $heading = str_replace( '{theme}', $this->product->get_name(), Loader::$labels['uninstall']['heading_theme'] );
131 $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', Loader::$labels['uninstall']['submit'] );
132 $options = $this->options_theme;
133 $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $options ) );
134 $info_disclosure_link = '<a href="#" class="info-disclosure-link">' . apply_filters( $this->product->get_slug() . '_themeGrill_sdk_info_collect_cta', Loader::$labels['uninstall']['cta_info'] ) . '</a>';
135
136 $options += $this->other;
137
138 ?>
139 <div class="tgsdk-theme-uninstall-feedback-drawer tgsdk-feedback">
140 <div class="popup--header">
141 <h5><?php echo wp_kses( $heading, array( 'span' => true ) ); ?> </h5>
142 <button class="toggle"><span>&times;</span></button>
143 </div><!--/.popup--header-->
144 <div class="popup--body">
145 <?php $this->render_options_list( $options ); ?>
146 </div><!--/.popup--body-->
147 <div class="popup--footer">
148 <div class="actions">
149 <?php
150 echo wp_kses_post( $info_disclosure_link );
151 echo wp_kses_post( $this->get_disclosure_labels() );
152 echo '<div class="buttons">';
153 echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function has an internal sanitization.
154 $button_submit,
155 'secondary',
156 $this->product->get_key() . 'tgsdk-deactivate-yes',
157 false,
158 array(
159 'data-after-text' => $button_submit,
160 'disabled' => true,
161 )
162 );
163 echo '</div>';
164 ?>
165 </div><!--/.actions-->
166 </div><!--/.popup--footer-->
167 </div>
168 <?php
169 }
170
171 /**
172 * Add feedback styles.
173 */
174 private function add_feedback_popup_style() {
175 ?>
176 <style>
177 .tgsdk-feedback {
178 background: #fff;
179 max-width: 400px;
180 z-index: 10000;
181 box-shadow: 0 0 15px -5px rgba(0, 0, 0, .5);
182 transition: all .3s ease-out;
183 }
184
185
186 .tgsdk-feedback .popup--header {
187 position: relative;
188 background-color: #2271b1;
189 }
190
191 .tgsdk-feedback .popup--header h5 {
192 margin: 0;
193 font-size: 16px;
194 padding: 15px;
195 color: #fff;
196 font-weight: 600;
197 text-align: center;
198 letter-spacing: .3px;
199 }
200
201 .tgsdk-feedback .popup--body {
202 padding: 15px;
203 }
204
205 .tgsdk-feedback .popup--form {
206 margin: 0;
207 font-size: 13px;
208 }
209
210 .tgsdk-feedback .popup--form input[type="radio"] {
211 <?php echo is_rtl() ? 'margin: 0 0 0 10px;' : 'margin: 0 10px 0 0;'; ?>
212 }
213
214 .tgsdk-feedback .popup--form input[type="radio"]:checked ~ textarea {
215 display: block;
216 }
217
218 .tgsdk-feedback .popup--form textarea {
219 width: 100%;
220 margin: 10px 0 0;
221 display: none;
222 max-height: 150px;
223 }
224
225 .tgsdk-feedback li {
226 display: flex;
227 align-items: center;
228 margin-bottom: 15px;
229 flex-wrap: wrap;
230 }
231
232 .tgsdk-feedback li label {
233 max-width: 90%;
234 }
235
236 .tgsdk-feedback li:last-child {
237 margin-bottom: 0;
238 }
239
240 .tgsdk-feedback .popup--footer {
241 padding: 0 15px 15px;
242 }
243
244 .tgsdk-feedback .actions {
245 display: flex;
246 flex-wrap: wrap;
247 }
248
249 .info-disclosure-link {
250 width: 100%;
251 margin-bottom: 15px;
252 }
253
254 .tgsdk-feedback .info-disclosure-content {
255 max-height: 0;
256 overflow: hidden;
257 width: 100%;
258 transition: .3s ease;
259 }
260
261 .tgsdk-feedback .info-disclosure-content.active {
262 max-height: 300px;
263 }
264
265 .tgsdk-feedback .info-disclosure-content p {
266 margin: 0;
267 }
268
269 .tgsdk-feedback .info-disclosure-content ul {
270 margin: 10px 0;
271 border-radius: 3px;
272 }
273
274 .tgsdk-feedback .info-disclosure-content ul li {
275 display: flex;
276 align-items: center;
277 justify-content: space-between;
278 margin-bottom: 0;
279 padding: 5px 0;
280 border-bottom: 1px solid #ccc;
281 }
282
283 .tgsdk-feedback .buttons {
284 display: flex;
285 width: 100%;
286 }
287
288 .tgsdk-feedback .buttons input:last-child {
289 <?php echo is_rtl() ? 'margin-right: auto;' : 'margin-left: auto;'; ?>
290 }
291
292 .tgsdk-theme-uninstall-feedback-drawer {
293 border-top-left-radius: 5px;
294 position: fixed;
295 top: 100%;
296 right: 15px;
297 }
298
299 .tgsdk-theme-uninstall-feedback-drawer.active {
300 transform: translateY(-100%);
301 }
302
303 .tgsdk-theme-uninstall-feedback-drawer .popup--header {
304 border-top-left-radius: 5px;
305 }
306
307 .tgsdk-theme-uninstall-feedback-drawer .popup--header .toggle {
308 position: absolute;
309 padding: 3px 0;
310 width: 30px;
311 top: -26px;
312 right: 0;
313 cursor: pointer;
314 border-top-left-radius: 5px;
315 border-top-right-radius: 5px;
316 font-size: 20px;
317 background-color: #2271b1;
318 color: #fff;
319 border: none;
320 line-height: 20px;
321 }
322
323 .tgsdk-theme-uninstall-feedback-drawer .toggle span {
324 margin: 0;
325 display: inline-block;
326 }
327
328 .tgsdk-theme-uninstall-feedback-drawer:not(.active) .toggle span {
329 transform: rotate(45deg);
330 }
331
332 .tgsdk-theme-uninstall-feedback-drawer .popup--header .toggle:hover {
333 background-color: #1880a5;
334 }
335
336
337 .tgsdk-plugin-uninstall-feedback-popup .popup--header:before {
338 content: "";
339 display: block;
340 position: absolute;
341 top: 50%;
342 transform: translateY(-50%);
343 <?php
344 echo is_rtl() ?
345 'right: -10px;
346 border-top: 20px solid transparent;
347 border-left: 20px solid #2271b1;
348 border-bottom: 20px solid transparent;' :
349 'left: -10px;
350 border-top: 20px solid transparent;
351 border-right: 20px solid #2271b1;
352 border-bottom: 20px solid transparent;';
353 ?>
354 }
355
356 .tgsdk-plugin-uninstall-feedback-popup {
357 display: none;
358 position: absolute;
359 white-space: normal;
360 width: 400px;
361 <?php echo is_rtl() ? 'right: calc( 100% + 15px );' : 'left: calc( 100% + 15px );'; ?> top: -15px;
362 }
363
364 .tgsdk-plugin-uninstall-feedback-popup.sending-feedback .popup--body i {
365 animation: rotation 2s infinite linear;
366 display: block;
367 float: none;
368 align-items: center;
369 width: 100%;
370 margin: 0 auto;
371 height: 100%;
372 background: transparent;
373 padding: 0;
374 }
375
376 .tgsdk-plugin-uninstall-feedback-popup.sending-feedback .popup--body i:before {
377 padding: 0;
378 background: transparent;
379 box-shadow: none;
380 color: #b4b9be
381 }
382
383
384 .tgsdk-plugin-uninstall-feedback-popup.active {
385 display: block;
386 }
387
388 tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>"] .deactivate {
389 position: relative;
390 }
391
392 body.tgsdk-feedback-open .tgsdk-feedback-overlay {
393 content: "";
394 display: block;
395 background-color: rgba(0, 0, 0, 0.5);
396 top: 0;
397 bottom: 0;
398 right: 0;
399 left: 0;
400 z-index: 10000;
401 position: fixed;
402 }
403
404 @media (max-width: 768px) {
405 .tgsdk-plugin-uninstall-feedback-popup {
406 position: fixed;
407 max-width: 100%;
408 margin: 0 auto;
409 left: 50%;
410 top: 50px;
411 transform: translateX(-50%);
412 }
413
414 .tgsdk-plugin-uninstall-feedback-popup .popup--header:before {
415 display: none;
416 }
417 }
418 </style>
419 <?php
420 }
421
422 /**
423 * Theme feedback drawer JS.
424 */
425 private function add_theme_feedback_drawer_js() {
426 $key = $this->product->get_key();
427 ?>
428 <script type="text/javascript" id="tgsdk-deactivate-js">
429 (function ($) {
430 $(document).ready(function () {
431 setTimeout(function () {
432 $('.tgsdk-theme-uninstall-feedback-drawer').addClass('active');
433 }, <?php echo absint( self::AUTO_TRIGGER_DEACTIVATE_WINDOW_SECONDS * 1000 ); ?> );
434
435 $('.tgsdk-theme-uninstall-feedback-drawer .toggle').on('click', function (e) {
436 e.preventDefault();
437 $('.tgsdk-theme-uninstall-feedback-drawer').toggleClass('active');
438 });
439
440 $('.info-disclosure-link').on('click', function (e) {
441 e.preventDefault();
442 $('.info-disclosure-content').toggleClass('active');
443 });
444
445 $('.tgsdk-theme-uninstall-feedback-drawer input[type="radio"]').on('change', function () {
446 var radio = $(this);
447 if (radio.parent().find('textarea').length > 0 &&
448 radio.parent().find('textarea').val().length === 0) {
449 $('#<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').attr('disabled', 'disabled');
450 radio.parent().find('textarea').on('keyup', function (e) {
451 if ($(this).val().length === 0) {
452 $('#<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').attr('disabled', 'disabled');
453 } else {
454 $('#<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').removeAttr('disabled');
455 }
456 });
457 } else {
458 $('#<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').removeAttr('disabled');
459 }
460 });
461
462 $('#<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').on('click', function (e) {
463 e.preventDefault();
464 e.stopPropagation();
465
466 var selectedOption = $(
467 '.tgsdk-theme-uninstall-feedback-drawer input[name="tgsdk-deactivate-option"]:checked');
468 $.post(ajaxurl, {
469 'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
470 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
471 'id': selectedOption.parent().attr('tgsdk-option-id'),
472 'msg': selectedOption.parent().find('textarea').val(),
473 'type': 'theme',
474 'key': '<?php echo esc_attr( $key ); ?>'
475 });
476 $('.tgsdk-theme-uninstall-feedback-drawer').fadeOut();
477 });
478 });
479 })(jQuery);
480
481 </script>
482 <?php
483 do_action( $this->product->get_key() . '_uninstall_feedback_after_js' );
484 }
485
486 /**
487 * Render the options list.
488 *
489 * @param array $options the options for the feedback form.
490 */
491 private function render_options_list( $options ) {
492 $key = $this->product->get_key();
493 $inputs_row_map = [
494 'text' => 1,
495 'textarea' => 2,
496 ];
497 ?>
498 <ul class="popup--form">
499 <?php
500 foreach ( $options as $idx => $attributes ) {
501 $title = Loader::$labels['uninstall']['options'][ $idx ]['title'];
502 $placeholder = array_key_exists( 'placeholder', Loader::$labels['uninstall']['options'][ $idx ] ) ? Loader::$labels['uninstall']['options'][ $idx ]['placeholder'] : '';
503 ?>
504 <li tgsdk-option-id="<?php echo esc_attr( $attributes['id'] ); ?>">
505 <input type="radio" name="tgsdk-deactivate-option"
506 id="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
507 <label for="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
508 <?php echo esc_attr( str_replace( '{theme}', $this->product->get_name(), $title ) ); ?>
509 </label>
510 <?php
511 if ( array_key_exists( 'type', $attributes ) ) {
512
513 echo '<textarea width="100%" rows="' . esc_attr( $inputs_row_map[ $attributes['type'] ] ) . '" name="comments" placeholder="' . esc_attr( $placeholder ) . '"></textarea>';
514 }
515 ?>
516 </li>
517 <?php } ?>
518 </ul>
519 <?php
520 }
521
522 /**
523 * Render plugin feedback popup.
524 */
525 private function render_plugin_feedback_popup() {
526 $button_cancel = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_cancel', Loader::$labels['uninstall']['button_cancel'] );
527 $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', Loader::$labels['uninstall']['button_submit'] );
528 $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $this->options_plugin ) );
529 $info_disclosure_link = '<a href="#" class="info-disclosure-link">' . apply_filters( $this->product->get_slug() . '_themeGrill_sdk_info_collect_cta', Loader::$labels['uninstall']['cta_info'] ) . '</a>';
530
531 $options += $this->other;
532 ?>
533 <div class="tgsdk-plugin-uninstall-feedback-popup tgsdk-feedback"
534 id="<?php echo esc_attr( $this->product->get_slug() . '_uninstall_feedback_popup' ); ?>">
535 <div class="popup--header">
536 <h5><?php echo wp_kses( Loader::$labels['uninstall']['heading_plugin'], array( 'span' => true ) ); ?> </h5>
537 </div><!--/.popup--header-->
538 <div class="popup--body">
539 <?php $this->render_options_list( $options ); ?>
540 </div><!--/.popup--body-->
541 <div class="popup--footer">
542 <div class="actions">
543 <?php
544 echo wp_kses_post( $info_disclosure_link );
545 echo wp_kses_post( $this->get_disclosure_labels() );
546 echo '<div class="buttons">';
547 echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
548 $button_cancel,
549 'secondary',
550 $this->product->get_key() . 'tgsdk-deactivate-no',
551 false
552 );
553 echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
554 $button_submit,
555 'primary',
556 $this->product->get_key() . 'tgsdk-deactivate-yes',
557 false,
558 array(
559 'data-after-text' => $button_submit,
560 'disabled' => true,
561 )
562 );
563 echo '</div>';
564 ?>
565 </div><!--/.actions-->
566 </div><!--/.popup--footer-->
567 </div>
568
569 <?php
570 }
571
572 /**
573 * Add plugin feedback popup JS
574 */
575 private function add_plugin_feedback_popup_js() {
576 $popup_id = '#' . $this->product->get_slug() . '_uninstall_feedback_popup';
577 $key = $this->product->get_key();
578 ?>
579 <script type="text/javascript" id="tgsdk-deactivate-js">
580 (function ($) {
581 $(document).ready(function () {
582 var targetElement = 'tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>/"] span.deactivate a';
583 var redirectUrl = $(targetElement).attr('href');
584 if ($('.tgsdk-feedback-overlay').length === 0) {
585 $('body').prepend('<div class="tgsdk-feedback-overlay"></div>');
586 }
587 $('<?php echo esc_attr( $popup_id ); ?> ').appendTo($(targetElement).parent());
588
589 $(targetElement).on('click', function (e) {
590 e.preventDefault();
591 $('<?php echo esc_attr( $popup_id ); ?> ').addClass('active');
592 $('body').addClass('tgsdk-feedback-open');
593 $('.tgsdk-feedback-overlay').on('click', function () {
594 $('<?php echo esc_attr( $popup_id ); ?> ').removeClass('active');
595 $('body').removeClass('tgsdk-feedback-open');
596 });
597 });
598
599 $('<?php echo esc_attr( $popup_id ); ?> .info-disclosure-link').on('click', function (e) {
600 e.preventDefault();
601 $(this).parent().find('.info-disclosure-content').toggleClass('active');
602 });
603
604 $('<?php echo esc_attr( $popup_id ); ?> input[type="radio"]').on('change', function () {
605 var radio = $(this);
606 if (radio.parent().find('textarea').length > 0 &&
607 radio.parent().find('textarea').val().length === 0) {
608 $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').attr('disabled', 'disabled');
609 radio.parent().find('textarea').on('keyup', function (e) {
610 if ($(this).val().length === 0) {
611 $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').attr('disabled', 'disabled');
612 } else {
613 $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').removeAttr('disabled');
614 }
615 });
616 } else {
617 $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').removeAttr('disabled');
618 }
619 });
620
621 $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>tgsdk-deactivate-no').on('click', function (e) {
622 e.preventDefault();
623 e.stopPropagation();
624 $(targetElement).unbind('click');
625 $('body').removeClass('tgsdk-feedback-open');
626 $('<?php echo esc_attr( $popup_id ); ?>').remove();
627 if (redirectUrl !== '') {
628 location.href = redirectUrl;
629 }
630 });
631
632 $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>tgsdk-deactivate-yes').on('click', function (e) {
633 e.preventDefault();
634 e.stopPropagation();
635 $(targetElement).unbind('click');
636 var selectedOption = $(
637 '<?php echo esc_attr( $popup_id ); ?> input[name="tgsdk-deactivate-option"]:checked');
638 var data = {
639 'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
640 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
641 'id': selectedOption.parent().attr('tgsdk-option-id'),
642 'msg': selectedOption.parent().find('textarea').val(),
643 'type': 'plugin',
644 'key': '<?php echo esc_attr( $key ); ?>'
645 };
646 $.ajax({
647 type: 'POST',
648 url: ajaxurl,
649 data: data,
650 complete() {
651 $('body').removeClass('tgsdk-feedback-open');
652 $('<?php echo esc_attr( $popup_id ); ?>').remove();
653 if (redirectUrl !== '') {
654 location.href = redirectUrl;
655 }
656 },
657 beforeSend() {
658 $('<?php echo esc_attr( $popup_id ); ?>').addClass('sending-feedback');
659 $('<?php echo esc_attr( $popup_id ); ?> .popup--footer').remove();
660 $('<?php echo esc_attr( $popup_id ); ?> .popup--body').html('<i class="dashicons dashicons-update-alt"></i>');
661 }
662 });
663 });
664 });
665 })(jQuery);
666
667 </script>
668 <?php
669 do_action( $this->product->get_key() . '_uninstall_feedback_after_js' );
670 }
671
672 /**
673 * Get the disclosure labels markup.
674 *
675 * @return string
676 */
677 private function get_disclosure_labels() {
678 $disclosure_new_labels = apply_filters( $this->product->get_slug() . '_themeGrill_sdk_disclosure_content_labels', [], $this->product );
679 $disclosure_labels = array_merge(
680 [
681 'title' => Loader::$labels['uninstall']['disclosure']['title'],
682 'items' => [
683 sprintf( Loader::$labels['uninstall']['disclosure']['version'], '<strong>', ucwords( $this->product->get_type() ), '</strong>', '<code>', $this->product->get_version(), '</code>' ),
684 sprintf( Loader::$labels['uninstall']['disclosure']['website'], '<strong>', '</strong>', '<code>', get_site_url(), '</code>' ),
685 sprintf( Loader::$labels['uninstall']['disclosure']['usage'], '<strong>', '</strong>', '<code>', ( time() - $this->product->get_install_time() ), 's</code>' ),
686 sprintf( Loader::$labels['uninstall']['disclosure']['reason'], '<strong>', '</strong>', '<i>', '</i>' ),
687 ],
688 ],
689 $disclosure_new_labels
690 );
691
692 $info_disclosure_content = '<div class="info-disclosure-content"><p>' . wp_kses_post( $disclosure_labels['title'] ) . '</p><ul>';
693 foreach ( $disclosure_labels['items'] as $disclosure_item ) {
694 $info_disclosure_content .= sprintf( '<li>%s</li>', wp_kses_post( $disclosure_item ) );
695 }
696 $info_disclosure_content .= '</ul></div>';
697
698 return $info_disclosure_content;
699 }
700
701 /**
702 * Randomizes the options array.
703 *
704 * @param array $options The options array.
705 */
706 public function randomize_options( $options ) {
707 $new = array();
708 $keys = array_keys( $options );
709 shuffle( $keys );
710
711 foreach ( $keys as $key ) {
712 $new[ $key ] = $options[ $key ];
713 }
714
715 return $new;
716 }
717
718 /**
719 * Called when the deactivate button is clicked.
720 */
721 public function post_deactivate() {
722 check_ajax_referer( (string) __CLASS__, 'nonce' );
723
724 $this->post_deactivate_or_cancel();
725
726 if ( empty( $_POST['id'] ) ) {
727
728 wp_send_json( [] );
729
730 return;
731 }
732 $this->call_api(
733 array(
734 'type' => 'deactivate',
735 'id' => sanitize_key( $_POST['id'] ),
736 'comment' => isset( $_POST['msg'] ) ? sanitize_textarea_field( $_POST['msg'] ) : '',
737 )
738 );
739 wp_send_json( [] );
740 }
741
742 /**
743 * Called when the deactivate/cancel button is clicked.
744 */
745 private function post_deactivate_or_cancel() {
746 if ( ! isset( $_POST['type'] ) || ! isset( $_POST['key'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
747 return;
748 }
749 if ( 'theme' !== $_POST['type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
750 return;
751 }
752
753 set_transient( 'tg_sdk_pause_' . sanitize_text_field( $_POST['key'] ), true, self::PAUSE_DEACTIVATE_WINDOW_DAYS * DAY_IN_SECONDS );//phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
754 }
755
756 /**
757 * Calls the API
758 *
759 * @param array $attributes The attributes of the post body.
760 *
761 * @return bool Is the request successful?
762 */
763 protected function call_api( $attributes ) {
764 $slug = $this->product->get_slug();
765 $version = $this->product->get_version();
766 $attributes['slug'] = $slug;
767 $attributes['version'] = $version;
768 $attributes['url'] = get_site_url();
769 $attributes['active_time'] = ( time() - $this->product->get_install_time() );
770
771 $response = wp_remote_post(
772 self::FEEDBACK_ENDPOINT,
773 array(
774 'body' => wp_json_encode( $attributes ),
775 'headers' => array(
776 'Content-Type' => 'application/json',
777 'User-Agent' => 'ThemeGrillSDK',
778 ),
779 )
780 );
781
782 return is_wp_error( $response );
783 }
784
785 /**
786 * Should we load this object?.
787 *
788 * @param Product $product Product object.
789 *
790 * @return bool Should we load the module?
791 */
792 public function can_load( $product ) {
793 if ( $this->is_from_partner( $product ) ) {
794 return false;
795 }
796 if ( $product->is_theme() && ( false !== get_transient( 'tg_sdk_pause_' . $product->get_key(), false ) ) ) {
797 return false;
798 }
799
800 if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
801 return true;
802 }
803 global $pagenow;
804
805 if ( ! isset( $pagenow ) || empty( $pagenow ) ) {
806 return false;
807 }
808
809 if ( $product->is_plugin() && 'plugins.php' !== $pagenow ) {
810 return false;
811
812 }
813 if ( $product->is_theme() && 'theme-install.php' !== $pagenow ) {
814 return false;
815 }
816
817 return true;
818 }
819
820 /**
821 * Loads module hooks.
822 *
823 * @param Product $product Product details.
824 *
825 * @return Uninstall_Feedback Current module instance.
826 */
827 public function load( $product ) {
828
829 if ( apply_filters( $product->get_key() . '_hide_uninstall_feedback', false ) ) {
830 return;
831 }
832
833 $this->product = $product;
834 add_action( 'admin_head', array( $this, 'load_resources' ) );
835 add_action( 'wp_ajax_' . $this->product->get_key() . '_uninstall_feedback', array( $this, 'post_deactivate' ) );
836
837 return $this;
838 }
839 }
840