PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 4.0.9
Visualizer – Tables & Charts Manager with Built-in AI Generator v4.0.9
4.0.9 4.0.8 4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 All 150 releases
← All changes | vendor/codeinwp/themeisle-sdk/src/Modules/Uninstall_feedback.php +528 -387 3.1.3 → 4.0.9 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' ) ) {
@@ -39,9 +40,9 @@
39 40 * Where to send the data.
40 41 *
41 42 * @var string Endpoint url.
42 43 */
43 - const FEEDBACK_ENDPOINT = 'http://feedback.themeisle.com/wordpress/wp-json/__pirate_feedback_/v1/feedback';
44 + const FEEDBACK_ENDPOINT = 'https://api.themeisle.com/tracking/uninstall';
44 45
45 46 /**
46 47 * Default options for plugins.
47 48 *
@@ -47,23 +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 - 'id' => 4,
57 + 'id4' => array(
58 + 'type' => 'textarea',
59 + 'id' => 4,
58 60 ),
59 - 'I no longer need the plugin' => array(
60 - 'id' => 5,
61 - 'type' => 'textarea',
62 - 'placeholder' => 'If you could improve one thing about our product, what would it be?',
61 + 'id5' => array(
62 + 'id' => 5,
63 + 'type' => 'textarea',
63 64 ),
64 - 'It\'s a temporary deactivation. I\'m just debugging an issue.' => array(
65 - 'id' => 6,
65 + 'id6' => array(
66 + 'type' => 'textarea',
67 + 'id' => 6,
66 68 ),
67 69 );
68 70 /**
69 71 * Default options for theme.
@@ -70,21 +72,23 @@
70 72 *
71 73 * @var array $options_theme The main options list for themes.
72 74 */
73 75 private $options_theme = array(
74 - 'I don\'t know how to make it look like demo' => array(
76 + 'id7' => array(
75 77 'id' => 7,
76 78 ),
77 - 'It lacks options' => array(
78 - 'id' => 8,
79 + 'id8' => array(
80 + 'type' => 'text',
81 + 'id' => 8,
79 82 ),
80 - 'Is not working with a plugin that I need' => array(
81 - 'id' => 9,
82 - 'type' => 'text',
83 - 'placeholder' => 'What is the name of the plugin',
83 + 'id9' => array(
84 + 'id' => 9,
85 + 'type' => 'text',
84 86 ),
85 - 'I want to try a new design, I don\'t like {theme} style' => array(
86 - 'id' => 10,
87 + 'id10' => array(
88 +
89 + 'title' => '',
90 + 'id' => 10,
87 91 ),
88 92 );
89 93 /**
90 94 * Default other option.
@@ -91,510 +95,626 @@
91 95 *
92 96 * @var array $other The other option
93 97 */
94 98 private $other = array(
95 - 'Other' => array(
96 - 'id' => 999,
97 - 'type' => 'textarea',
98 - 'placeholder' => 'cmon cmon tell us',
99 + 'id999' => array(
100 + 'id' => 999,
101 + 'type' => 'textarea',
99 102 ),
100 103 );
104 +
101 105 /**
102 - * Default heading for plugin.
103 - *
104 - * @var string $heading_plugin The heading of the modal
106 + * Loads the additional resources
105 107 */
106 - private $heading_plugin = 'Quick Feedback <span>Because we care about our clients, please leave us feedback.</span>';
107 - /**
108 - * Default heading for theme.
109 - *
110 - * @var string $heading_theme The heading of the modal
111 - */
112 - private $heading_theme = 'Looking to change {theme}? <span> What does not work for you?</span>';
113 - /**
114 - * Default submit button action text.
115 - *
116 - * @var string $button_submit The text of the deactivate button
117 - */
118 - private $button_submit = 'Submit &amp; Deactivate';
119 - /**
120 - * Default cancel button.
121 - *
122 - * @var string $button_cancel The text of the cancel button
123 - */
124 - private $button_cancel = 'Skip &amp; Deactivate';
108 + public function load_resources() {
109 + $screen = get_current_screen();
125 110
111 + if ( ! $screen || ! in_array( $screen->id, array( 'theme-install', 'plugins' ) ) ) {
112 + return;
113 + }
114 +
115 + $this->add_feedback_popup_style();
116 +
117 + if ( $this->product->get_type() === 'theme' ) {
118 + $this->add_theme_feedback_drawer_js();
119 + $this->render_theme_feedback_popup();
120 +
121 + return;
122 + }
123 + $this->add_plugin_feedback_popup_js();
124 + $this->render_plugin_feedback_popup();
125 + }
126 +
126 127 /**
127 - * Loads the additional resources
128 + * Render theme feedback drawer.
128 129 */
129 - function load_resources() {
130 - add_thickbox();
130 + private function render_theme_feedback_popup() {
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'] );
133 + $options = $this->options_theme;
134 + $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $options ) );
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>';
131 136
132 - $id = $this->product->get_key() . '_deactivate';
137 + $options += $this->other;
133 138
134 - $this->add_css( $this->product->get_type(), $this->product->get_key() );
135 - $this->add_js( $this->product->get_type(), $this->product->get_key(), '#TB_inline?' . apply_filters( $this->product->get_key() . '_feedback_deactivate_attributes', 'width=600&height=550' ) . '&inlineId=' . $id );
136 -
137 - echo '<div id="' . $id . '" style="display:none;" class="themeisle-deactivate-box">' . $this->get_html( $this->product->get_type(), $this->product->get_key() ) . '</div>';
139 + ?>
140 + <div class="ti-theme-uninstall-feedback-drawer ti-feedback">
141 + <div class="popup--header">
142 + <h5><?php echo wp_kses( $heading, array( 'span' => true ) ); ?></h5>
143 + <?php $this->do_popup_header_after_heading_action( 'theme' ); ?>
144 + <button class="toggle"><span>&times;</span></button>
145 + </div><!--/.popup--header-->
146 + <div class="popup--body">
147 + <?php $this->render_options_list( $options ); ?>
148 + </div><!--/.popup--body-->
149 + <div class="popup--footer">
150 + <div class="actions">
151 + <?php
152 + echo wp_kses_post( $info_disclosure_link );
153 + echo wp_kses_post( $this->get_disclosure_labels() );
154 + echo '<div class="buttons">';
155 + echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function has an internal sanitization.
156 + $button_submit,
157 + 'secondary',
158 + $this->product->get_key() . 'ti-deactivate-yes',
159 + false,
160 + array(
161 + 'data-after-text' => $button_submit,
162 + 'disabled' => true,
163 + )
164 + );
165 + echo '</div>';
166 + ?>
167 + </div><!--/.actions-->
168 + </div><!--/.popup--footer-->
169 + </div>
170 + <?php
138 171 }
139 172
140 173 /**
141 - * Loads the css
142 - *
143 - * @param string $type The type of product.
144 - * @param string $key The product key.
174 + * Add feedback styles.
145 175 */
146 - function add_css( $type, $key ) {
147 - $key = esc_attr( $key );
148 - $suffix = Product::THEME_TYPE === $type ? 'theme-install-php' : 'plugins-php';
149 - $icon = esc_attr( apply_filters( $this->product->get_slug() . '_uninstall_feedback_icon', '' ) );
150 - if ( empty( $icon ) ) {
151 - $icon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNi1jMTQyIDc5LjE2MDkyNCwgMjAxNy8wNy8xMy0wMTowNjozOSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpDNkVDM0M4RkYxMzMxMUU3OEMyMkQ0NTIxRTVEQ0ZBRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpDNkVDM0M5MEYxMzMxMUU3OEMyMkQ0NTIxRTVEQ0ZBRiI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkM2RUMzQzhERjEzMzExRTc4QzIyRDQ1MjFFNURDRkFGIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkM2RUMzQzhFRjEzMzExRTc4QzIyRDQ1MjFFNURDRkFGIi8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+KBNOswAAFtFJREFUeNrkWwmUXVWV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';
152 - }
176 + private function add_feedback_popup_style() {
153 177 ?>
154 - <style type="text/css" id="<?php echo $key; ?>ti-deactivate-css">
155 - input[name="ti-deactivate-option"] ~ div {
156 - display: none;
178 + <style>
179 + .ti-feedback {
180 + background: #fff;
181 + max-width: 400px;
182 + z-index: 10000;
183 + box-shadow: 0 0 15px -5px rgba(0, 0, 0, .5);
184 + transition: all .3s ease-out;
157 185 }
158 186
159 - input[name="ti-deactivate-option"]:checked ~ div {
160 - display: block;
161 - }
162 187
163 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_window.thickbox-loading:before {
164 - background: none !important;
188 + .ti-feedback .popup--header {
189 + position: relative;
190 + background-color: #23A1CE;
165 191 }
166 192
167 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_title {
168 - background: url('<?php echo $icon; ?>') 40px 30px no-repeat;
169 - border: none;
170 - box-sizing: border-box;
171 - color: #373e40;
172 - font-size: 24px;
173 - font-weight: 700;
174 - height: 90px;
175 - padding: 40px 40px 0 120px;
176 - text-transform: uppercase;
177 - width: 100%;
193 + .ti-feedback .popup--header h5 {
194 + margin: 0;
195 + font-size: 16px;
196 + padding: 15px;
197 + color: #fff;
198 + font-weight: 600;
199 + text-align: center;
200 + letter-spacing: .3px;
178 201 }
179 202
180 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content ul i {
181 - padding-left: 5px;
182 - margin: 0 1px;
203 + .ti-feedback .popup--body {
204 + padding: 15px;
183 205 }
184 206
185 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content ul strong {
186 - width: 125px;
187 - display: block;
207 + .ti-feedback .popup--form {
188 208 margin: 0;
189 - float: left;
209 + font-size: 13px;
190 210 }
191 211
192 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content ul {
193 - margin-left: 39px;
194 - margin-top: 2px;
195 - padding-top: 0px;
212 + .ti-feedback .popup--form input[type="radio"] {
213 + <?php echo is_rtl() ? 'margin: 0 0 0 10px;' : 'margin: 0 10px 0 0;'; ?>
196 214 }
197 215
198 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content p {
199 - font-style: italic;
200 - margin-bottom: 0px;
216 + .ti-feedback .popup--form input[type="radio"]:checked ~ textarea {
217 + display: block;
201 218 }
202 219
203 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure-content {
220 + .ti-feedback .popup--form textarea {
221 + width: 100%;
222 + margin: 10px 0 0;
204 223 display: none;
224 + max-height: 150px;
205 225 }
206 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container.<?php echo $key; ?>-container-disc-open #<?php echo $key; ?>-info-disclosure-content {
207 - display: block;
208 - position:absolute;
209 - bottom: 100px;
226 +
227 + .ti-feedback li {
228 + display: flex;
229 + align-items: center;
230 + margin-bottom: 15px;
231 + flex-wrap: wrap;
210 232 }
211 233
212 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container.<?php echo $key; ?>-container-disc-open #<?php echo $key; ?>-info-disclosure {
213 - top: -130px;
234 + .ti-feedback li label {
235 + max-width: 90%;
214 236 }
215 237
216 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container.<?php echo $key; ?>-container-disc-open {
217 - height: 590px !important;
238 + .ti-feedback li:last-child {
239 + margin-bottom: 0;
218 240 }
219 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #<?php echo $key; ?>-info-disclosure {
220 - position: absolute;
221 - top: -50px;
222 - font-size: 13px;
223 - color: #8d9192;
224 - font-weight: 400;
225 - right: 40px;
241 +
242 + .ti-feedback .popup--footer {
243 + padding: 0 15px 15px;
226 244 }
227 245
228 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container div.actions {
229 - box-sizing: border-box;
230 - padding: 30px 40px;
231 - background-color: #eaeaea;
246 + .ti-feedback .actions {
247 + display: flex;
248 + flex-wrap: wrap;
232 249 }
233 250
234 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button {
235 - background: #ec5d60;
236 - border: none;
237 - box-shadow: none;
238 - color: #ffffff;
239 - font-size: 15px;
240 - font-weight: 700;
241 - height: auto;
242 - line-height: 20px;
243 - padding: 10px 15px;
244 - text-transform: uppercase;
245 - -webkit-transition: 0.3s ease;
246 - -moz-transition: 0.3s ease;
247 - -ms-transition: 0.3s ease;
248 - -o-transition: 0.3s ease;
249 - transition: 0.3s ease;
251 + .info-disclosure-link {
252 + width: 100%;
253 + margin-bottom: 15px;
250 254 }
251 255
252 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary {
253 - background: transparent;
254 - box-shadow: none;
255 - color: #8d9192;
256 - font-weight: 400;
257 - float: right;
258 - line-height: 40px;
259 - padding: 0;
260 - text-decoration: underline;
261 - text-shadow: none;
262 - text-transform: none;
256 + .ti-feedback .info-disclosure-content {
257 + max-height: 0;
258 + overflow: hidden;
259 + width: 100%;
260 + transition: .3s ease;
263 261 }
264 262
265 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:hover {
266 - background: #e83f42;
263 + .ti-feedback .info-disclosure-content.active {
264 + max-height: 300px;
267 265 }
268 266
269 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary:hover {
270 - background: transparent;
267 + .ti-feedback .info-disclosure-content p {
268 + margin: 0;
271 269 }
272 270
273 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:focus {
274 - box-shadow: none;
275 - outline: none;
271 + .ti-feedback .info-disclosure-content ul {
272 + margin: 10px 0;
273 + border-radius: 3px;
276 274 }
277 275
278 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:active {
279 - box-shadow: none;
280 - transform: translateY(0);
276 + .ti-feedback .info-disclosure-content ul li {
277 + display: flex;
278 + align-items: center;
279 + justify-content: space-between;
280 + margin-bottom: 0;
281 + padding: 5px 0;
282 + border-bottom: 1px solid #ccc;
281 283 }
282 284
283 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button:disabled {
284 - cursor: not-allowed;
285 + .ti-feedback .buttons {
286 + display: flex;
287 + width: 100%;
285 288 }
286 289
287 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container input.button.button-primary:hover {
288 - text-decoration: none;
290 + .ti-feedback .buttons input:last-child {
291 + <?php echo is_rtl() ? 'margin-right: auto;' : 'margin-left: auto;'; ?>
289 292 }
290 293
291 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container div.revive_network-container {
292 - background-color: #ffffff;
294 + .ti-theme-uninstall-feedback-drawer {
295 + border-top-left-radius: 5px;
296 + position: fixed;
297 + top: 100%;
298 + right: 15px;
293 299 }
294 300
295 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list {
296 - margin: 0;
301 + .ti-theme-uninstall-feedback-drawer.active {
302 + transform: translateY(-100%);
297 303 }
298 304
299 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li {
300 - color: #373e40;
301 - font-size: 13px;
302 - margin-bottom: 5px;
305 + .ti-theme-uninstall-feedback-drawer .popup--header {
306 + border-top-left-radius: 5px;
303 307 }
304 308
305 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li label {
306 - margin-left: 10px;
307 - line-height: 28px;
308 - font-size: 15px;
309 + .ti-theme-uninstall-feedback-drawer .popup--header .toggle {
310 + position: absolute;
311 + padding: 3px 0;
312 + width: 30px;
313 + top: -26px;
314 + right: 0;
315 + cursor: pointer;
316 + border-top-left-radius: 5px;
317 + border-top-right-radius: 5px;
318 + font-size: 20px;
319 + background-color: #23A1CE;
320 + color: #fff;
321 + border: none;
322 + line-height: 20px;
309 323 }
310 324
311 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list input[type=radio] {
312 - margin-top: 1px;
325 + .ti-theme-uninstall-feedback-drawer .toggle span {
326 + margin: 0;
327 + display: inline-block;
313 328 }
314 329
315 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container #TB_ajaxContent {
316 - box-sizing: border-box;
317 - height: auto !important;
318 - padding: 20px 40px;
319 - width: 100% !important;
330 + .ti-theme-uninstall-feedback-drawer:not(.active) .toggle span {
331 + transform: rotate(45deg);
320 332 }
321 333
322 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container li div textarea {
323 - padding: 10px 15px;
324 - width: 100%;
334 + .ti-theme-uninstall-feedback-drawer .popup--header .toggle:hover {
335 + background-color: #1880a5;
325 336 }
326 337
327 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container ul.ti-list li div {
328 - margin: 10px 30px;
329 - }
330 338
331 - .<?php echo $key; ?>-container #TB_title #TB_ajaxWindowTitle {
332 - box-sizing: border-box;
339 + .ti-plugin-uninstall-feedback-popup .popup--header:before {
340 + content: "";
333 341 display: block;
334 - float: none;
335 - font-weight: 700;
336 - line-height: 1;
337 - padding: 0;
338 - text-align: left;
339 - width: 100%;
342 + position: absolute;
343 + top: 50%;
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 + ?>
340 356 }
341 357
342 - .<?php echo $key; ?>-container #TB_title #TB_ajaxWindowTitle span {
343 - color: #8d9192;
344 - display: block;
345 - font-size: 15px;
346 - font-weight: 400;
347 - margin-top: 5px;
348 - text-transform: none;
358 + .ti-plugin-uninstall-feedback-popup {
359 + display: none;
360 + position: absolute;
361 + white-space: normal;
362 + width: 400px;
363 + <?php echo is_rtl() ? 'right: calc( 100% + 15px );' : 'left: calc( 100% + 15px );'; ?> top: -15px;
349 364 }
350 365
351 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container .actions {
366 + .ti-plugin-uninstall-feedback-popup.sending-feedback .popup--body i {
367 + animation: rotation 2s infinite linear;
368 + display: block;
369 + float: none;
370 + align-items: center;
352 371 width: 100%;
353 - display: block;
354 - position: absolute;
355 - left: 0;
356 - bottom: 0;
372 + margin: 0 auto;
373 + height: 100%;
374 + background: transparent;
375 + padding: 0;
357 376 }
358 377
359 - .theme-install-php .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon:before {
360 - font-size: 32px;
378 + .ti-plugin-uninstall-feedback-popup.sending-feedback .popup--body i:before {
379 + padding: 0;
380 + background: transparent;
381 + box-shadow: none;
382 + color: #b4b9be
361 383 }
362 384
363 - .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon {
364 - color: #eee;
365 - }
366 385
367 - .<?php echo $key; ?>-container #TB_closeWindowButton {
368 - left: auto;
369 - right: -5px;
370 - top: -35px;
371 - color: #eee;
386 + .ti-plugin-uninstall-feedback-popup.active {
387 + display: block;
372 388 }
373 389
374 - .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon {
375 - text-align: right;
376 - line-height: 25px;
377 - width: 25px;
378 - height: 25px;
390 + tr[data-plugin^="<?php echo esc_attr( $this->product->get_slug() ); ?>"] .deactivate {
391 + position: relative;
379 392 }
380 393
381 - .<?php echo $key; ?>-container #TB_closeWindowButton:focus .tb-close-icon {
382 - box-shadow: none;
383 - outline: none;
394 + body.ti-feedback-open .ti-feedback-overlay {
395 + content: "";
396 + display: block;
397 + background-color: rgba(0, 0, 0, 0.5);
398 + top: 0;
399 + bottom: 0;
400 + right: 0;
401 + left: 0;
402 + z-index: 10000;
403 + position: fixed;
384 404 }
385 405
386 - .<?php echo $key; ?>-container #TB_closeWindowButton .tb-close-icon:before {
387 - font: normal 25px dashicons;
388 - }
406 + @media (max-width: 768px) {
407 + .ti-plugin-uninstall-feedback-popup {
408 + position: fixed;
409 + max-width: 100%;
410 + margin: 0 auto;
411 + left: 50%;
412 + top: 50px;
413 + transform: translateX(-50%);
414 + }
389 415
390 - body.<?php echo $suffix; ?> .<?php echo $key; ?>-container {
391 - margin: auto !important;
392 - height: 500px !important;
393 - top: 0 !important;
394 - left: 0 !important;
395 - bottom: 0 !important;
396 - right: 0 !important;
397 - width: 600px !important;
416 + .ti-plugin-uninstall-feedback-popup .popup--header:before {
417 + display: none;
418 + }
398 419 }
399 420 </style>
400 421 <?php
401 - do_action( $this->product->get_key() . '_uninstall_feedback_after_css' );
402 422 }
403 423
404 424 /**
405 - * Loads the js.
406 - *
407 - * @param string $type The type of product.
408 - * @param string $key The product key.
409 - * @param string $src The url that will hijack the deactivate button url.
425 + * Theme feedback drawer JS.
410 426 */
411 - function add_js( $type, $key, $src ) {
412 - $heading = Product::PLUGIN_TYPE === $type ? $this->heading_plugin : str_replace( '{theme}', $this->product->get_name(), $this->heading_theme );
413 - $key = esc_attr( $key );
414 - $heading = apply_filters( $this->product->get_key() . '_feedback_deactivate_heading', $heading );
427 + private function add_theme_feedback_drawer_js() {
428 + $key = $this->product->get_key();
415 429 ?>
416 430 <script type="text/javascript" id="ti-deactivate-js">
417 431 (function ($) {
418 432 $(document).ready(function () {
419 - var auto_trigger = false;
420 - var target_element = 'tr[data-plugin^="<?php echo $this->product->get_slug(); ?>/"] span.deactivate a';
433 + setTimeout(function () {
434 + $('.ti-theme-uninstall-feedback-drawer').addClass('active');
435 + }, <?php echo absint( self::AUTO_TRIGGER_DEACTIVATE_WINDOW_SECONDS * 1000 ); ?> );
436 +
437 + $('.ti-theme-uninstall-feedback-drawer .toggle').on('click', function (e) {
438 + e.preventDefault();
439 + $('.ti-theme-uninstall-feedback-drawer').toggleClass('active');
440 + });
441 +
442 + $('.info-disclosure-link').on('click', function (e) {
443 + e.preventDefault();
444 + $('.info-disclosure-content').toggleClass('active');
445 + });
446 +
447 + $('.ti-theme-uninstall-feedback-drawer input[type="radio"]').on('change', function () {
448 + var radio = $(this);
449 + if (radio.parent().find('textarea').length > 0 &&
450 + radio.parent().find('textarea').val().length === 0) {
451 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
452 + radio.parent().find('textarea').on('keyup', function (e) {
453 + if ($(this).val().length === 0) {
454 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
455 + } else {
456 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
457 + }
458 + });
459 + } else {
460 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').removeAttr('disabled');
461 + }
462 + });
463 +
464 + $('#<?php echo esc_attr( $key ); ?>ti-deactivate-yes').on('click', function (e) {
465 + e.preventDefault();
466 + e.stopPropagation();
467 +
468 + var selectedOption = $(
469 + '.ti-theme-uninstall-feedback-drawer input[name="ti-deactivate-option"]:checked');
470 + $.post(ajaxurl, {
471 + 'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
472 + 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
473 + 'id': selectedOption.parent().attr('ti-option-id'),
474 + 'msg': selectedOption.parent().find('textarea').val(),
475 + 'type': 'theme',
476 + 'key': '<?php echo esc_attr( $key ); ?>'
477 + });
478 + $('.ti-theme-uninstall-feedback-drawer').fadeOut();
479 + });
480 + });
481 + })(jQuery);
482 +
483 + </script>
484 + <?php
485 + do_action( $this->product->get_key() . '_uninstall_feedback_after_js' );
486 + }
487 +
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 + /**
502 + * Render the options list.
503 + *
504 + * @param array $options the options for the feedback form.
505 + */
506 + private function render_options_list( $options ) {
507 + $key = $this->product->get_key();
508 + $inputs_row_map = [
509 + 'text' => 1,
510 + 'textarea' => 2,
511 + ];
512 + ?>
513 + <ul class="popup--form">
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 + ?>
519 + <li ti-option-id="<?php echo esc_attr( $attributes['id'] ); ?>">
520 + <input type="radio" name="ti-deactivate-option"
521 + id="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
522 + <label for="<?php echo esc_attr( $key . $attributes['id'] ); ?>">
523 + <?php echo esc_attr( str_replace( '{theme}', $this->product->get_name(), $title ) ); ?>
524 + </label>
421 525 <?php
422 - if ( 'theme' === $type ) {
423 - ?>
424 - auto_trigger = true;
425 - if ($('a.ti-auto-anchor').length == 0) {
426 - $('body').append($('<a class="ti-auto-anchor" href=""></a>'));
526 + if ( array_key_exists( 'type', $attributes ) ) {
527 +
528 + echo '<textarea width="100%" rows="' . esc_attr( $inputs_row_map[ $attributes['type'] ] ) . '" name="comments" placeholder="' . esc_attr( $placeholder ) . '"></textarea>';
427 529 }
428 - target_element = 'a.ti-auto-anchor';
429 - <?php
430 - }
431 530 ?>
531 + </li>
532 + <?php } ?>
533 + </ul>
534 + <?php
535 + }
432 536
433 - if (auto_trigger) {
434 - setTimeout(function () {
435 - $('a.ti-auto-anchor').trigger('click');
436 - }, <?php echo self::AUTO_TRIGGER_DEACTIVATE_WINDOW_SECONDS * 1000; ?> );
537 + /**
538 + * Render plugin feedback popup.
539 + */
540 + private function render_plugin_feedback_popup() {
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'] );
543 + $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $this->options_plugin ) );
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>';
545 +
546 + $options += $this->other;
547 + ?>
548 + <div class="ti-plugin-uninstall-feedback-popup ti-feedback"
549 + id="<?php echo esc_attr( $this->product->get_slug() . '_uninstall_feedback_popup' ); ?>">
550 + <div class="popup--header">
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' ); ?>
553 + </div><!--/.popup--header-->
554 + <div class="popup--body">
555 + <?php $this->render_options_list( $options ); ?>
556 + </div><!--/.popup--body-->
557 + <div class="popup--footer">
558 + <div class="actions">
559 + <?php
560 + echo wp_kses_post( $info_disclosure_link );
561 + echo wp_kses_post( $this->get_disclosure_labels() );
562 + echo '<div class="buttons">';
563 + echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
564 + $button_cancel,
565 + 'secondary',
566 + $this->product->get_key() . 'ti-deactivate-no',
567 + false
568 + );
569 + echo get_submit_button( //phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped, Function internals are escaped.
570 + $button_submit,
571 + 'primary',
572 + $this->product->get_key() . 'ti-deactivate-yes',
573 + false,
574 + array(
575 + 'data-after-text' => $button_submit,
576 + 'disabled' => true,
577 + )
578 + );
579 + echo '</div>';
580 + ?>
581 + </div><!--/.actions-->
582 + </div><!--/.popup--footer-->
583 + </div>
584 +
585 + <?php
586 + }
587 +
588 + /**
589 + * Add plugin feedback popup JS
590 + */
591 + private function add_plugin_feedback_popup_js() {
592 + $popup_id = '#' . $this->product->get_slug() . '_uninstall_feedback_popup';
593 + $key = $this->product->get_key();
594 + ?>
595 + <script type="text/javascript" id="ti-deactivate-js">
596 + (function ($) {
597 + $(document).ready(function () {
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 + if ($('.ti-feedback-overlay').length === 0) {
602 + $('body').prepend('<div class="ti-feedback-overlay"></div>');
437 603 }
438 - $(document).on('thickbox:removed', function () {
439 - $.post(ajaxurl, {
440 - 'action': '<?php echo $key . '_uninstall_feedback'; ?>',
441 - 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
442 - 'type': '<?php echo $type; ?>',
443 - 'key': '<?php echo $key; ?>'
604 + $('<?php echo esc_attr( $popup_id ); ?> ').appendTo($deactivateLink.parent());
605 +
606 + $deactivateLink.on('click', function (e) {
607 + e.preventDefault();
608 + $('<?php echo esc_attr( $popup_id ); ?> ').addClass('active');
609 + $('body').addClass('ti-feedback-open');
610 + $('.ti-feedback-overlay').on('click', function () {
611 + $('<?php echo esc_attr( $popup_id ); ?> ').removeClass('active');
612 + $('body').removeClass('ti-feedback-open');
444 613 });
445 614 });
446 - var href = $(target_element).attr('href');
447 - $('#<?php echo $key; ?>ti-deactivate-no').attr('data-ti-action', href).on('click', function (e) {
615 +
616 + $('<?php echo esc_attr( $popup_id ); ?> .info-disclosure-link').on('click', function (e) {
448 617 e.preventDefault();
449 - e.stopPropagation();
450 -
451 - $('body').unbind('thickbox:removed');
452 - tb_remove();
453 - var redirect = $(this).attr('data-ti-action');
454 - if (redirect !== '') {
455 - location.href = redirect;
456 - }
618 + $(this).parent().find('.info-disclosure-content').toggleClass('active');
457 619 });
458 620
459 - $('#<?php echo $key; ?> ul.ti-list label, #<?php echo $key; ?> ul.ti-list input[name="ti-deactivate-option"]').on('click', function (e) {
460 - $('#<?php echo $key; ?>ti-deactivate-yes').val($('#<?php echo $key; ?>ti-deactivate-yes').attr('data-after-text'));
461 -
462 - var radio = $(this).prop('tagName') === 'LABEL' ? $(this).parent() : $(this);
463 - if (radio.parent().find('textarea').length > 0 && radio.parent().find('textarea').val().length === 0) {
464 - $('#<?php echo $key; ?>ti-deactivate-yes').attr('disabled', 'disabled');
465 - radio.parent().find('textarea').on('keyup', function (ee) {
621 + $('<?php echo esc_attr( $popup_id ); ?> input[type="radio"]').on('change', function () {
622 + var radio = $(this);
623 + if (radio.parent().find('textarea').length > 0 &&
624 + radio.parent().find('textarea').val().length === 0) {
625 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').attr('disabled', 'disabled');
626 + radio.parent().find('textarea').on('keyup', function (e) {
466 627 if ($(this).val().length === 0) {
467 - $('#<?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');
468 629 } else {
469 - $('#<?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');
470 631 }
471 632 });
472 633 } else {
473 - $('#<?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');
474 635 }
475 636 });
476 - $("#<?php echo $key; ?>-info-disclosure").on('click', function () {
477 - $("#TB_window").toggleClass("<?php echo $key; ?>-container-disc-open");
478 - return false;
479 - });
480 - $('#<?php echo $key; ?>ti-deactivate-yes').attr('data-ti-action', href).on('click', function (e) {
637 +
638 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-no').on('click', function (e) {
481 639 e.preventDefault();
482 640 e.stopPropagation();
483 - $.post(ajaxurl, {
484 - 'action': '<?php echo $key . '_uninstall_feedback'; ?>',
485 - 'nonce': '<?php echo wp_create_nonce( (string) __CLASS__ ); ?>',
486 - 'id': $('#<?php echo $key; ?> input[name="ti-deactivate-option"]:checked').parent().attr('ti-option-id'),
487 - 'msg': $('#<?php echo $key; ?> input[name="ti-deactivate-option"]:checked').parent().find('textarea').val(),
488 - 'type': '<?php echo $type; ?>',
489 - });
490 - var redirect = $(this).attr('data-ti-action');
491 - if (redirect != '') {
492 - location.href = redirect;
493 - } else {
494 - $('body').unbind('thickbox:removed');
495 - tb_remove();
641 + $deactivateLink.unbind('click');
642 + $('body').removeClass('ti-feedback-open');
643 + $('<?php echo esc_attr( $popup_id ); ?>').remove();
644 + if (redirectUrl !== '') {
645 + location.href = redirectUrl;
496 646 }
497 647 });
498 648
499 - $(target_element).attr('name', '<?php echo wp_kses( $heading, array( 'span' => array() ) ); ?>').attr('href', '<?php echo $src; ?>').addClass('thickbox');
500 - var thicbox_timer;
501 - $(target_element).on('click', function () {
502 - tiBindThickbox();
649 + $('<?php echo esc_attr( $popup_id ); ?> #<?php echo esc_attr( $key ); ?>ti-deactivate-yes').on('click', function (e) {
650 + e.preventDefault();
651 + e.stopPropagation();
652 + $deactivateLink.unbind('click');
653 + var selectedOption = $(
654 + '<?php echo esc_attr( $popup_id ); ?> input[name="ti-deactivate-option"]:checked');
655 + var data = {
656 + 'action': '<?php echo esc_attr( $key ) . '_uninstall_feedback'; ?>',
657 + 'nonce': '<?php echo esc_attr( wp_create_nonce( (string) __CLASS__ ) ); ?>',
658 + 'id': selectedOption.parent().attr('ti-option-id'),
659 + 'msg': selectedOption.parent().find('textarea').val(),
660 + 'type': 'plugin',
661 + 'key': '<?php echo esc_attr( $key ); ?>'
662 + };
663 + $.ajax({
664 + type: 'POST',
665 + url: ajaxurl,
666 + data: data,
667 + complete() {
668 + $('body').removeClass('ti-feedback-open');
669 + $('<?php echo esc_attr( $popup_id ); ?>').remove();
670 + if (redirectUrl !== '') {
671 + location.href = redirectUrl;
672 + }
673 + },
674 + beforeSend() {
675 + $('<?php echo esc_attr( $popup_id ); ?>').addClass('sending-feedback');
676 + $('<?php echo esc_attr( $popup_id ); ?> .popup--footer').remove();
677 + $('<?php echo esc_attr( $popup_id ); ?> .popup--body').html('<i class="dashicons dashicons-update-alt"></i>');
678 + }
679 + });
503 680 });
504 -
505 - function tiBindThickbox() {
506 - var thicbox_timer = setTimeout(function () {
507 - if ($("#<?php echo esc_html( $key ); ?>").is(":visible")) {
508 - $("body").trigger('thickbox:iframe:loaded');
509 - $("#TB_window").addClass("<?php echo $key; ?>-container");
510 - clearTimeout(thicbox_timer);
511 - $('body').unbind('thickbox:removed');
512 - } else {
513 - tiBindThickbox();
514 - }
515 - }, 100);
516 - }
517 681 });
518 682 })(jQuery);
683 +
519 684 </script>
520 685 <?php
521 -
522 686 do_action( $this->product->get_key() . '_uninstall_feedback_after_js' );
523 687 }
524 688
525 689 /**
526 - * Generates the HTML.
690 + * Get the disclosure labels markup.
527 691 *
528 - * @param string $type The type of product.
529 - * @param string $key The product key.
692 + * @return string
530 693 */
531 - function get_html( $type, $key ) {
532 - $options = Product::PLUGIN_TYPE === $type ? $this->options_plugin : $this->options_theme;
533 - $button_cancel = Product::PLUGIN_TYPE === $type ? $this->button_cancel : 'Skip';
534 - $button_submit = Product::PLUGIN_TYPE === $type ? $this->button_submit : 'Submit';
535 - $options = $this->randomize_options( apply_filters( $this->product->get_key() . '_feedback_deactivate_options', $options ) );
536 - $button_submit = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_submit', $button_submit );
537 - $button_cancel = apply_filters( $this->product->get_key() . '_feedback_deactivate_button_cancel', $button_cancel );
538 -
539 - $options += $this->other;
540 -
541 - $list = '';
542 - foreach ( $options as $title => $attributes ) {
543 - $id = $attributes['id'];
544 - $list .= '<li ti-option-id="' . $id . '"><input type="radio" name="ti-deactivate-option" id="' . $key . $id . '"><label for="' . $key . $id . '">' . str_replace( '{theme}', $this->product->get_name(), $title ) . '</label>';
545 - if ( array_key_exists( 'type', $attributes ) ) {
546 - $list .= '<div>';
547 - $placeholder = array_key_exists( 'placeholder', $attributes ) ? $attributes['placeholder'] : '';
548 - switch ( $attributes['type'] ) {
549 - case 'text':
550 - $list .= '<textarea style="width: 100%" rows="1" name="comments" placeholder="' . $placeholder . '"></textarea>';
551 - break;
552 - case 'textarea':
553 - $list .= '<textarea style="width: 100%" rows="2" name="comments" placeholder="' . $placeholder . '"></textarea>';
554 - break;
555 - }
556 - $list .= '</div>';
557 - }
558 - $list .= '</li>';
559 - }
560 -
694 + private function get_disclosure_labels() {
561 695 $disclosure_new_labels = apply_filters( $this->product->get_slug() . '_themeisle_sdk_disclosure_content_labels', [], $this->product );
562 696 $disclosure_labels = array_merge(
563 697 [
564 - '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'],
565 699 'items' => [
566 - sprintf( '%s %s version %s %s %s %s', '<strong>', ucwords( $this->product->get_type() ), '</strong>', '<code>', $this->product->get_version(), '</code>' ),
567 - sprintf( '%s Uninstall reason %s %s Selected reson 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>' ),
568 705 ],
569 706 ],
570 707 $disclosure_new_labels
571 708 );
572 709
573 - $info_disclosure_link = '<a href="#" id="' . $this->product->get_key() . '-info-disclosure">' . apply_filters( $this->product->get_slug() . '_themeisle_sdk_info_collect_cta', 'What info do we collect?' ) . '</a>';
574 - $info_disclosure_content = '<div id="' . $this->product->get_key() . '-info-disclosure-content"><p>' . wp_kses_post( $disclosure_labels['title'] ) . '</p><ul>';
710 + $info_disclosure_content = '<div class="info-disclosure-content"><p>' . wp_kses_post( $disclosure_labels['title'] ) . '</p><ul>';
575 711 foreach ( $disclosure_labels['items'] as $disclosure_item ) {
576 712 $info_disclosure_content .= sprintf( '<li>%s</li>', wp_kses_post( $disclosure_item ) );
577 713 }
578 714 $info_disclosure_content .= '</ul></div>';
579 715
580 - return
581 - '<div id="' . $this->product->get_key() . '"><ul class="ti-list">' . $list . '</ul>'
582 - . $info_disclosure_content
583 - . '<div class="actions">'
584 - . get_submit_button(
585 - $button_submit,
586 - 'secondary',
587 - $this->product->get_key() . 'ti-deactivate-yes',
588 - false,
589 - array(
590 - 'data-after-text' => $button_submit,
591 - 'disabled' => true,
592 - )
593 - )
594 - . wp_kses_post( $info_disclosure_link )
595 - . get_submit_button( $button_cancel, 'primary', $this->product->get_key() . 'ti-deactivate-no', false )
596 - . '</div></div>';
716 + return $info_disclosure_content;
597 717 }
598 718
599 719 /**
600 720 * Randomizes the options array.
@@ -600,9 +720,9 @@
600 720 * Randomizes the options array.
601 721 *
602 722 * @param array $options The options array.
603 723 */
604 - function randomize_options( $options ) {
724 + public function randomize_options( $options ) {
605 725 $new = array();
606 726 $keys = array_keys( $options );
607 727 shuffle( $keys );
608 728
@@ -615,9 +735,9 @@
615 735
616 736 /**
617 737 * Called when the deactivate button is clicked.
618 738 */
619 - function post_deactivate() {
739 + public function post_deactivate() {
620 740 check_ajax_referer( (string) __CLASS__, 'nonce' );
621 741
622 742 $this->post_deactivate_or_cancel();
623 743
@@ -629,10 +749,10 @@
629 749 }
630 750 $this->call_api(
631 751 array(
632 752 'type' => 'deactivate',
633 - 'id' => $_POST['id'],
634 - 'comment' => isset( $_POST['msg'] ) ? $_POST['msg'] : '',
753 + 'id' => sanitize_key( $_POST['id'] ),
754 + 'comment' => isset( $_POST['msg'] ) ? sanitize_textarea_field( $_POST['msg'] ) : '',
635 755 )
636 756 );
637 757 wp_send_json( [] );
638 758
@@ -641,16 +761,16 @@
641 761 /**
642 762 * Called when the deactivate/cancel button is clicked.
643 763 */
644 764 private function post_deactivate_or_cancel() {
645 - 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.
646 766 return;
647 767 }
648 - if ( 'theme' !== $_POST['type'] ) {
768 + if ( 'theme' !== $_POST['type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Missing, Nonce already present in caller function.
649 769 return;
650 770 }
651 771
652 - 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.
653 773
654 774 }
655 775
656 776 /**
@@ -660,13 +780,29 @@
660 780 *
661 781 * @return bool Is the request succesfull?
662 782 */
663 783 protected function call_api( $attributes ) {
664 - $slug = $this->product->get_slug();
665 - $version = $this->product->get_version();
666 - $attributes['slug'] = $slug;
667 - $attributes['version'] = $version;
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() );
668 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 );
804 +
669 805 $response = wp_remote_post(
670 806 self::FEEDBACK_ENDPOINT,
671 807 array(
672 808 'body' => $attributes,
@@ -718,8 +854,13 @@
718 854 *
719 855 * @return Uninstall_Feedback Current module instance.
720 856 */
721 857 public function load( $product ) {
858 +
859 + if ( apply_filters( $product->get_key() . '_hide_uninstall_feedback', false ) ) {
860 + return;
861 + }
862 +
722 863 $this->product = $product;
723 864 add_action( 'admin_head', array( $this, 'load_resources' ) );
724 865 add_action( 'wp_ajax_' . $this->product->get_key() . '_uninstall_feedback', array( $this, 'post_deactivate' ) );
725 866