PluginProbe
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization / trunk
Optimole – Optimize Images | Convert WebP & AVIF | CDN & Lazy Load | Image Optimization vtrunk
4.2.14 4.2.13 4.2.12 4.2.11 4.2.10 4.2.9 4.2.8 4.2.7 4.2.6 4.2.5 2.5.5 2.5.6 2.5.7 3.0.0 3.0.1 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.11.0 3.11.1 3.11.2 3.11.3 3.12.0 All 135 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Modules/Uninstall_feedback.php +135 -118 3.0.0 → trunk View file →
@@ -11,8 +11,9 @@
11 11
12 12 namespace ThemeisleSDK\Modules;
13 13
14 14 use ThemeisleSDK\Common\Abstract_Module;
15 +use ThemeisleSDK\Loader;
15 16 use ThemeisleSDK\Product;
16 17
17 18 // Exit if accessed directly.
18 19 if ( ! defined( 'ABSPATH' ) ) {
@@ -47,27 +48,24 @@
47 48 *
48 49 * @var array $options_plugin The main options list for plugins.
49 50 */
50 51 private $options_plugin = array(
51 - 'I found a better plugin' => array(
52 - 'id' => 3,
53 - 'type' => 'text',
54 - 'placeholder' => 'What\'s the plugin\'s name?',
52 + 'id3' => array(
53 + 'id' => 3,
54 + 'type' => 'text',
55 +
55 56 ),
56 - 'I could not get the plugin to work' => array(
57 - 'type' => 'textarea',
58 - 'placeholder' => 'What problem are you experiencing?',
59 - 'id' => 4,
57 + 'id4' => array(
58 + 'type' => 'textarea',
59 + 'id' => 4,
60 60 ),
61 - 'I no longer need the plugin' => array(
62 - 'id' => 5,
63 - 'type' => 'textarea',
64 - 'placeholder' => 'If you could improve one thing about our product, what would it be?',
61 + 'id5' => array(
62 + 'id' => 5,
63 + 'type' => 'textarea',
65 64 ),
66 - 'It\'s a temporary deactivation. I\'m just debugging an issue.' => array(
67 - 'type' => 'textarea',
68 - 'placeholder' => 'What problem are you experiencing?',
69 - 'id' => 6,
65 + 'id6' => array(
66 + 'type' => 'textarea',
67 + 'id' => 6,
70 68 ),
71 69 );
72 70 /**
73 71 * Default options for theme.
@@ -74,23 +72,23 @@
74 72 *
75 73 * @var array $options_theme The main options list for themes.
76 74 */
77 75 private $options_theme = array(
78 - 'I don\'t know how to make it look like demo' => array(
76 + 'id7' => array(
79 77 'id' => 7,
80 78 ),
81 - 'It lacks options' => array(
82 - 'placeholder' => 'What option is missing?',
83 - 'type' => 'text',
84 - 'id' => 8,
79 + 'id8' => array(
80 + 'type' => 'text',
81 + 'id' => 8,
85 82 ),
86 - 'Is not working with a plugin that I need' => array(
87 - 'id' => 9,
88 - 'type' => 'text',
89 - 'placeholder' => 'What is the name of the plugin',
83 + 'id9' => array(
84 + 'id' => 9,
85 + 'type' => 'text',
90 86 ),
91 - 'I want to try a new design, I don\'t like {theme} style' => array(
92 - 'id' => 10,
87 + 'id10' => array(
88 +
89 + 'title' => '',
90 + 'id' => 10,
93 91 ),
94 92 );
95 93 /**
96 94 * Default other option.
@@ -97,43 +95,18 @@
97 95 *
98 96 * @var array $other The other option
99 97 */
100 98 private $other = array(
101 - 'Other' => array(
102 - 'id' => 999,
103 - 'type' => 'textarea',
104 - 'placeholder' => 'What can we do better?',
99 + 'id999' => array(
100 + 'id' => 999,
101 + 'type' => 'textarea',
105 102 ),
106 103 );
107 - /**
108 - * Default heading for plugin.
109 - *
110 - * @var string $heading_plugin The heading of the modal
111 - */
112 - private $heading_plugin = 'What\'s wrong?';
113 - /**
114 - * Default heading for theme.
115 - *
116 - * @var string $heading_theme The heading of the modal
117 - */
118 - private $heading_theme = 'What does not work for you in {theme}?';
119 - /**
120 - * Default submit button action text.
121 - *
122 - * @var string $button_submit The text of the deactivate button
123 - */
124 - private $button_submit = 'Submit & Deactivate';
125 - /**
126 - * Default cancel button.
127 - *
128 - * @var string $button_cancel The text of the cancel button
129 - */
130 - private $button_cancel = 'Skip & Deactivate';
131 104
132 105 /**
133 106 * Loads the additional resources
134 107 */
135 - function load_resources() {
108 + public function load_resources() {
136 109 $screen = get_current_screen();
137 110
138 111 if ( ! $screen || ! in_array( $screen->id, array( 'theme-install', 'plugins' ) ) ) {
139 112 return;
@@ -154,13 +127,13 @@
154 127 /**
155 128 * Render theme feedback drawer.
156 129 */
157 130 private function render_theme_feedback_popup() {
158 - $heading = str_replace( '{theme}', $this->product->get_name(), $this->heading_theme );
159 - $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', 'Submit' );
131 + $heading = str_replace( '{theme}', $this->product->get_name(), Loader::$labels['uninstall']['heading_theme'] );
132 + $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', Loader::$labels['uninstall']['submit'] );
160 133 $options = $this->options_theme;
161 134 $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $options ) );
162 - $info_disclosure_link = '<a href="#" class="info-disclosure-link">' . apply_filters( $this->product->get_slug() . '_themeisle_sdk_info_collect_cta', 'What info do we collect?' ) . '</a>';
135 + $info_disclosure_link = '<a href="#" class="info-disclosure-link">' . apply_filters( $this->product->get_slug() . '_themeisle_sdk_info_collect_cta', Loader::$labels['uninstall']['cta_info'] ) . '</a>';
163 136
164 137 $options += $this->other;
165 138
166 139 ?>
@@ -165,9 +138,10 @@
165 138
166 139 ?>
167 140 <div class="ti-theme-uninstall-feedback-drawer ti-feedback">
168 141 <div class="popup--header">
169 - <h5><?php echo wp_kses( $heading, array( 'span' => true ) ); ?> </h5>
142 + <h5><?php echo wp_kses( $heading, array( 'span' => true ) ); ?></h5>
143 + <?php $this->do_popup_header_after_heading_action( 'theme' ); ?>
170 144 <button class="toggle"><span>&times;</span></button>
171 145 </div><!--/.popup--header-->
172 146 <div class="popup--body">
173 147 <?php $this->render_options_list( $options ); ?>
@@ -177,9 +151,9 @@
177 151 <?php
178 152 echo wp_kses_post( $info_disclosure_link );
179 153 echo wp_kses_post( $this->get_disclosure_labels() );
180 154 echo '<div class="buttons">';
181 - echo get_submit_button(
155 + echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function has an internal sanitization.
182 156 $button_submit,
183 157 'secondary',
184 158 $this->product->get_key() . 'ti-deactivate-yes',
185 159 false,
@@ -235,9 +209,9 @@
235 209 font-size: 13px;
236 210 }
237 211
238 212 .ti-feedback .popup--form input[type="radio"] {
239 - margin: 0 10px 0 0;
213 + <?php echo is_rtl() ? 'margin: 0 0 0 10px;' : 'margin: 0 10px 0 0;'; ?>
240 214 }
241 215
242 216 .ti-feedback .popup--form input[type="radio"]:checked ~ textarea {
243 217 display: block;
@@ -313,9 +287,9 @@
313 287 width: 100%;
314 288 }
315 289
316 290 .ti-feedback .buttons input:last-child {
317 - margin-left: auto;
291 + <?php echo is_rtl() ? 'margin-right: auto;' : 'margin-left: auto;'; ?>
318 292 }
319 293
320 294 .ti-theme-uninstall-feedback-drawer {
321 295 border-top-left-radius: 5px;
@@ -365,15 +339,21 @@
365 339 .ti-plugin-uninstall-feedback-popup .popup--header:before {
366 340 content: "";
367 341 display: block;
368 342 position: absolute;
369 - border: 20px solid #23A1CE;
370 - left: -10px;
371 343 top: 50%;
372 - border-top: 20px solid transparent;
373 - border-bottom: 20px solid transparent;
374 - border-left: 0;
375 344 transform: translateY(-50%);
345 + <?php
346 + echo is_rtl() ?
347 + 'right: -10px;
348 + border-top: 20px solid transparent;
349 + border-left: 20px solid #23A1CE;
350 + border-bottom: 20px solid transparent;' :
351 + 'left: -10px;
352 + border-top: 20px solid transparent;
353 + border-right: 20px solid #23A1CE;
354 + border-bottom: 20px solid transparent;';
355 + ?>
376 356 }
377 357
378 358 .ti-plugin-uninstall-feedback-popup {
379 359 display: none;
@@ -379,10 +359,9 @@
379 359 display: none;
380 360 position: absolute;
381 361 white-space: normal;
382 362 width: 400px;
383 - left: 100%;
384 - top: -15px;
363 + <?php echo is_rtl() ? 'right: calc( 100% + 15px );' : 'left: calc( 100% + 15px );'; ?> top: -15px;
385 364 }
386 365
387 366 .ti-plugin-uninstall-feedback-popup.sending-feedback .popup--body i {
388 367 animation: rotation 2s infinite linear;
@@ -407,9 +386,9 @@
407 386 .ti-plugin-uninstall-feedback-popup.active {
408 387 display: block;
409 388 }
410 389
411 - tr[data-plugin^="<?php echo $this->product->get_slug(); ?>"] .deactivate {
390 + tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>"] .deactivate {
412 391 position: relative;
413 392 }
414 393
415 394 body.ti-feedback-open .ti-feedback-overlay {
@@ -468,22 +447,22 @@
468 447 $('.ti-theme-uninstall-feedback-drawer input[type="radio"]').on('change', function () {
469 448 var radio = $(this);
470 449 if (radio.parent().find('textarea').length > 0 &&
471 450 radio.parent().find('textarea').val().length === 0) {
472 - $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
451 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
473 452 radio.parent().find('textarea').on('keyup', function (e) {
474 453 if ($(this).val().length === 0) {
475 - $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
454 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
476 455 } else {
477 - $('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
456 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
478 457 }
479 458 });
480 459 } else {
481 - $('#<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
460 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
482 461 }
483 462 });
484 463
485 - $('#<?php echo $key; ?>ti-deactivate-yes').on('click', function (e) {
464 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').on('click', function (e) {
486 465 e.preventDefault();
487 466 e.stopPropagation();
488 467
489 468 var selectedOption = $(
@@ -489,9 +468,9 @@
489 468 var selectedOption = $(
490 469 '.ti-theme-uninstall-feedback-drawer input[name="ti-deactivate-option"]:checked');
491 470 $.post(ajaxurl, {
492 471 'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
493 - 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
472 + 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
494 473 'id': selectedOption.parent().attr('ti-option-id'),
495 474 'msg': selectedOption.parent().find('textarea').val(),
496 475 'type': 'theme',
497 476 'key': '<?php echo esc_attr( $key ); ?>'
@@ -506,8 +485,21 @@
506 485 do_action( $this->product->get_key() . '_uninstall_feedback_after_js' );
507 486 }
508 487
509 488 /**
489 + * Fires after the popup header heading, allowing products to output extra markup.
490 + *
491 + * @param string $context Popup context. Either `theme` or `plugin`.
492 + */
493 + private function do_popup_header_after_heading_action( $context ) {
494 + do_action(
495 + $this->product->get_key() . '_uninstall_feedback_popup_header_after_heading',
496 + $this->product,
497 + $context
498 + );
499 + }
500 +
501 + /**
510 502 * Render the options list.
511 503 *
512 504 * @param array $options the options for the feedback form.
513 505 */
@@ -518,18 +510,23 @@
518 510 'textarea' => 2,
519 511 ];
520 512 ?>
521 513 <ul class="popup--form">
522 - <?php foreach ( $options as $title => $attributes ) { ?>
514 + <?php
515 + foreach ( $options as $idx => $attributes ) {
516 + $title = Loader::$labels['uninstall']['options'][ $idx ]['title'];
517 + $placeholder = array_key_exists( 'placeholder', Loader::$labels['uninstall']['options'][ $idx ] ) ? Loader::$labels['uninstall']['options'][ $idx ]['placeholder'] : '';
518 + ?>
523 519 <li ti-option-id="<?php echo esc_attr( $attributes['id'] ); ?>">
524 - <input type="radio" name="ti-deactivate-option" id="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
520 + <input type="radio" name="ti-deactivate-option"
521 + id="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
525 522 <label for="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
526 - <?php echo str_replace( '{theme}', $this->product->get_name(), $title ); ?>
523 + <?php echo esc_attr( str_replace( '{theme}', $this->product->get_name(), $title ) ); ?>
527 524 </label>
528 525 <?php
529 526 if ( array_key_exists( 'type', $attributes ) ) {
530 - $placeholder = array_key_exists( 'placeholder', $attributes ) ? $attributes['placeholder'] : '';
531 - echo '<textarea width="100%" rows="' . $inputs_row_map[ $attributes['type'] ] . '" name="comments" placeholder="' . esc_attr( $placeholder ) . '"></textarea>';
527 +
528 + echo '<textarea width="100%" rows="' . esc_attr( $inputs_row_map[ $attributes['type'] ] ) . '" name="comments" placeholder="' . esc_attr( $placeholder ) . '"></textarea>';
532 529 }
533 530 ?>
534 531 </li>
535 532 <?php } ?>
@@ -540,18 +537,20 @@
540 537 /**
541 538 * Render plugin feedback popup.
542 539 */
543 540 private function render_plugin_feedback_popup() {
544 - $button_cancel = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_cancel', $this->button_cancel );
545 - $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', $this->button_submit );
541 + $button_cancel = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_cancel', Loader::$labels['uninstall']['button_cancel'] );
542 + $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', Loader::$labels['uninstall']['button_submit'] );
546 543 $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $this->options_plugin ) );
547 - $info_disclosure_link = '<a href="#" class="info-disclosure-link">' . apply_filters( $this->product->get_slug() . '_themeisle_sdk_info_collect_cta', 'What info do we collect?' ) . '</a>';
544 + $info_disclosure_link = '<a href="#" class="info-disclosure-link">' . apply_filters( $this->product->get_slug() . '_themeisle_sdk_info_collect_cta', Loader::$labels['uninstall']['cta_info'] ) . '</a>';
548 545
549 546 $options += $this->other;
550 547 ?>
551 - <div class="ti-plugin-uninstall-feedback-popup ti-feedback" id="<?php echo esc_attr( $this->product->get_slug() . '_uninstall_feedback_popup' ); ?>">
548 + <div class="ti-plugin-uninstall-feedback-popup ti-feedback"
549 + id="<?php echo esc_attr( $this->product->get_slug() . '_uninstall_feedback_popup' ); ?>">
552 550 <div class="popup--header">
553 - <h5><?php echo wp_kses( $this->heading_plugin, array( 'span' => true ) ); ?> </h5>
551 + <h5><?php echo wp_kses( Loader::$labels['uninstall']['heading_plugin'], array( 'span' => true ) ); ?> </h5>
552 + <?php $this->do_popup_header_after_heading_action( 'plugin' ); ?>
554 553 </div><!--/.popup--header-->
555 554 <div class="popup--body">
556 555 <?php $this->render_options_list( $options ); ?>
557 556 </div><!--/.popup--body-->
@@ -560,15 +559,15 @@
560 559 <?php
561 560 echo wp_kses_post( $info_disclosure_link );
562 561 echo wp_kses_post( $this->get_disclosure_labels() );
563 562 echo '<div class="buttons">';
564 - echo get_submit_button(
563 + echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
565 564 $button_cancel,
566 565 'secondary',
567 566 $this->product->get_key() . 'ti-deactivate-no',
568 567 false
569 568 );
570 - echo get_submit_button(
569 + echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
571 570 $button_submit,
572 571 'primary',
573 572 $this->product->get_key() . 'ti-deactivate-yes',
574 573 false,
@@ -595,16 +594,17 @@
595 594 ?>
596 595 <script type="text/javascript" id="ti-deactivate-js">
597 596 (function ($) {
598 597 $(document).ready(function () {
599 - var targetElement = 'tr[data-plugin^="<?php echo $this->product->get_slug(); ?>/"] span.deactivate a';
600 - var redirectUrl = $(targetElement).attr('href');
598 + var targetElement = 'tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>/"] span.deactivate a';
599 + var $deactivateLink = $(targetElement);
600 + var redirectUrl = $deactivateLink.attr('href');
601 601 if ($('.ti-feedback-overlay').length === 0) {
602 602 $('body').prepend('<div class="ti-feedback-overlay"></div>');
603 603 }
604 - $('<?php echo esc_attr( $popup_id ); ?> ').appendTo($(targetElement).parent());
604 + $('<?php echo esc_attr( $popup_id ); ?> ').appendTo($deactivateLink.parent());
605 605
606 - $(targetElement).on('click', function (e) {
606 + $deactivateLink.on('click', function (e) {
607 607 e.preventDefault();
608 608 $('<?php echo esc_attr( $popup_id ); ?> ').addClass('active');
609 609 $('body').addClass('ti-feedback-open');
610 610 $('.ti-feedback-overlay').on('click', function () {
@@ -621,25 +621,25 @@
621 621 $('<?php echo esc_attr( $popup_id ); ?> input[type="radio"]').on('change', function () {
622 622 var radio = $(this);
623 623 if (radio.parent().find('textarea').length > 0 &&
624 624 radio.parent().find('textarea').val().length === 0) {
625 - $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
625 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
626 626 radio.parent().find('textarea').on('keyup', function (e) {
627 627 if ($(this).val().length === 0) {
628 - $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
628 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
629 629 } else {
630 - $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
630 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
631 631 }
632 632 });
633 633 } else {
634 - $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').removeAttr('disabled');
634 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
635 635 }
636 636 });
637 637
638 - $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-no').on('click', function (e) {
638 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-no').on('click', function (e) {
639 639 e.preventDefault();
640 640 e.stopPropagation();
641 - $(targetElement).unbind('click');
641 + $deactivateLink.unbind('click');
642 642 $('body').removeClass('ti-feedback-open');
643 643 $('<?php echo esc_attr( $popup_id ); ?>').remove();
644 644 if (redirectUrl !== '') {
645 645 location.href = redirectUrl;
@@ -645,17 +645,17 @@
645 645 location.href = redirectUrl;
646 646 }
647 647 });
648 648
649 - $('<?php echo esc_attr( $popup_id ); ?> #<?php echo $key; ?>ti-deactivate-yes').on('click', function (e) {
649 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').on('click', function (e) {
650 650 e.preventDefault();
651 651 e.stopPropagation();
652 - $(targetElement).unbind('click');
652 + $deactivateLink.unbind('click');
653 653 var selectedOption = $(
654 654 '<?php echo esc_attr( $popup_id ); ?> input[name="ti-deactivate-option"]:checked');
655 655 var data = {
656 656 'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
657 - 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
657 + 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
658 658 'id': selectedOption.parent().attr('ti-option-id'),
659 659 'msg': selectedOption.parent().find('textarea').val(),
660 660 'type': 'plugin',
661 661 'key': '<?php echo esc_attr( $key ); ?>'
@@ -694,13 +694,15 @@
694 694 private function get_disclosure_labels() {
695 695 $disclosure_new_labels = apply_filters( $this->product->get_slug() . '_themeisle_sdk_disclosure_content_labels', [], $this->product );
696 696 $disclosure_labels = array_merge(
697 697 [
698 - 'title' => 'Below is a detailed view of all data that ThemeIsle will receive if you fill in this survey. No domain name, email address or IP addresses are transmited after you submit the survey.',
698 + 'title' => Loader::$labels['uninstall']['disclosure']['title'],
699 699 'items' => [
700 - sprintf( '%s %s version %s %s %s %s', '<strong>', ucwords( $this->product->get_type() ), '</strong>', '<code>', $this->product->get_version(), '</code>' ),
701 - sprintf( '%sCurrent website:%s %s %s %s', '<strong>', '</strong>', '<code>', get_site_url(), '</code>' ),
702 - sprintf( '%s Uninstall reason %s %s Selected reason from the above survey %s ', '<strong>', '</strong>', '<i>', '</i>' ),
700 + sprintf( Loader::$labels['uninstall']['disclosure']['version'], '<strong>', ucwords( $this->product->get_type() ), '</strong>', '<code>', $this->product->get_version(), '</code>' ),
701 + sprintf( Loader::$labels['uninstall']['disclosure']['website'], '<strong>', '</strong>', '<code>', get_site_url(), '</code>' ),
702 + sprintf( Loader::$labels['uninstall']['disclosure']['usage'], '<strong>', '</strong>', '<code>', ( time() - $this->product->get_install_time() ), 's</code>' ),
703 + sprintf( Loader::$labels['uninstall']['disclosure']['reason'], '<strong>', '</strong>', '<i>', '</i>' ),
704 + sprintf( Loader::$labels['uninstall']['disclosure']['diagnostics'], '<strong>', '</strong>' ),
703 705 ],
704 706 ],
705 707 $disclosure_new_labels
706 708 );
@@ -718,9 +720,9 @@
718 720 * Randomizes the options array.
719 721 *
720 722 * @param array $options The options array.
721 723 */
722 - function randomize_options( $options ) {
724 + public function randomize_options( $options ) {
723 725 $new = array();
724 726 $keys = array_keys( $options );
725 727 shuffle( $keys );
726 728
@@ -733,9 +735,9 @@
733 735
734 736 /**
735 737 * Called when the deactivate button is clicked.
736 738 */
737 - function post_deactivate() {
739 + public function post_deactivate() {
738 740 check_ajax_referer( (string) __CLASS__, 'nonce' );
739 741
740 742 $this->post_deactivate_or_cancel();
741 743
@@ -747,10 +749,10 @@
747 749 }
748 750 $this->call_api(
749 751 array(
750 752 'type' => 'deactivate',
751 - 'id' => $_POST['id'],
752 - 'comment' => isset( $_POST['msg'] ) ? $_POST['msg'] : '',
753 + 'id' => sanitize_key( $_POST['id'] ),
754 + 'comment' => isset( $_POST['msg'] ) ? sanitize_textarea_field( $_POST['msg'] ) : '',
753 755 )
754 756 );
755 757 wp_send_json( [] );
756 758
@@ -759,16 +761,16 @@
759 761 /**
760 762 * Called when the deactivate/cancel button is clicked.
761 763 */
762 764 private function post_deactivate_or_cancel() {
763 - if ( ! isset( $_POST['type'] ) || ! isset( $_POST['key'] ) ) {
765 + if ( ! isset( $_POST['type'] ) || ! isset( $_POST['key'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
764 766 return;
765 767 }
766 - if ( 'theme' !== $_POST['type'] ) {
768 + if ( 'theme' !== $_POST['type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
767 769 return;
768 770 }
769 771
770 - set_transient( 'ti_sdk_pause_' . $_POST['key'], true, self::PAUSE_DEACTIVATE_WINDOW_DAYS * DAY_IN_SECONDS );
772 + set_transient( 'ti_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.
771 773
772 774 }
773 775
774 776 /**
@@ -778,13 +780,28 @@
778 780 *
779 781 * @return bool Is the request succesfull?
780 782 */
781 783 protected function call_api( $attributes ) {
782 - $slug = $this->product->get_slug();
783 - $version = $this->product->get_version();
784 - $attributes['slug'] = $slug;
785 - $attributes['version'] = $version;
786 - $attributes['url'] = get_site_url();
784 + $slug = $this->product->get_slug();
785 + $version = $this->product->get_version();
786 + $attributes['slug'] = $slug;
787 + $attributes['version'] = $version;
788 + $attributes['url'] = get_site_url();
789 + $attributes['active_time'] = ( time() - $this->product->get_install_time() );
790 +
791 + /**
792 + * Piggyback the compact crash summary on the same request, regardless
793 + * of the logging consent — disclosed in the survey data collection
794 + * notice. Only crashes attributed to this product are ever stored.
795 + */
796 + if ( class_exists( 'ThemeisleSDK\Modules\Crash_Reporter' ) ) {
797 + $crashes = Crash_Reporter::get_uninstall_summary( $this->product );
798 + if ( ! empty( $crashes ) ) {
799 + $attributes['crashes'] = wp_json_encode( $crashes );
800 + }
801 + }
802 +
803 + $attributes = apply_filters( 'themeisle_sdk_uninstall_feedback_data', $attributes, $this->product );
787 804
788 805 $response = wp_remote_post(
789 806 self::FEEDBACK_ENDPOINT,
790 807 array(