PluginProbe ʕ •ᴥ•ʔ
Appointment Booking Plugin – LatePoint | Calendar & Scheduling for WordPress / 5.6.10
Appointment Booking Plugin – LatePoint | Calendar & Scheduling for WordPress v5.6.10
5.6.10 5.6.9 5.6.8 5.6.7 5.6.6 5.6.5 5.6.4 5.6.3 5.6.2 5.6.1 5.6.0 5.5.2 5.5.1 5.5.0 5.4.2 trunk 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.1.8 5.1.9 5.1.91 5.1.92 5.1.93 5.1.94 5.2.0 5.2.1 5.2.10 5.2.11 5.2.2 5.2.3 5.2.4 5.2.5 5.2.6 5.2.7 5.2.8 5.2.9 5.3.0 5.3.1 5.3.2 5.4.0 5.4.1
latepoint / lib / kit / bsf-analytics / modules / deactivation-survey / classes / class-deactivation-survey-feedback.php
latepoint / lib / kit / bsf-analytics / modules / deactivation-survey / classes Last commit date
class-deactivation-survey-feedback.php 2 months ago
class-deactivation-survey-feedback.php
319 lines
1 <?php
2 /**
3 * Deactivation Survey Feedback.
4 *
5 * @package bsf-analytics
6 */
7
8 // Exit if accessed directly.
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit;
11 }
12
13 if ( ! class_exists( 'Deactivation_Survey_Feedback' ) ) {
14
15 /**
16 * Class Deactivation_Survey_Feedback.
17 */
18 class Deactivation_Survey_Feedback {
19
20 /**
21 * Feedback URL.
22 *
23 * @var string
24 */
25 private static $feedback_api_endpoint = 'api/plugin-deactivate';
26
27 /**
28 * Instance
29 *
30 * @access private
31 * @var object Class object.
32 * @since 1.1.6
33 */
34 private static $instance;
35
36 /**
37 * Initiator
38 *
39 * @since 1.1.6
40 * @return object initialized object of class.
41 */
42 public static function get_instance() {
43 if ( ! isset( self::$instance ) ) {
44 self::$instance = new self();
45 }
46 return self::$instance;
47 }
48
49 /**
50 * Constructor
51 */
52 public function __construct() {
53 add_action( 'admin_enqueue_scripts', array( $this, 'load_form_styles' ) );
54 add_action( 'wp_ajax_uds_plugin_deactivate_feedback', array( $this, 'send_plugin_deactivate_feedback' ) );
55 }
56
57 /**
58 * Render feedback HTML on plugins.php admin page only.
59 *
60 * This function renders the feedback form HTML on the plugins.php admin page.
61 * It takes an optional string parameter $id for the form wrapper ID and an optional array parameter $args for customizing the form.
62 *
63 * @since 1.1.6
64 * @param array $args Optional. Custom arguments for the form. Defaults to an empty array.
65 * @return void
66 */
67 public static function show_feedback_form( array $args = array() ) {
68
69 // Return if not in admin.
70 if ( ! is_admin() ) {
71 return;
72 }
73
74 // Set default arguments for the feedback form.
75 $defaults = array(
76 'source' => 'User Deactivation Survey',
77 'popup_logo' => '',
78 'plugin_slug' => 'user-deactivation-survey',
79 'plugin_version' => '',
80 'popup_title' => __( 'Quick Feedback' ),
81 'support_url' => 'https://brainstormforce.com/contact/',
82 'popup_reasons' => self::get_default_reasons(),
83 'popup_description' => __( 'If you have a moment, please share why you are deactivating the plugin.' ),
84 'show_on_screens' => array( 'plugins' ),
85 );
86
87 // Parse the arguments with defaults.
88 $args = wp_parse_args( $args, $defaults );
89 $id = ! empty( $args['id'] ) ? sanitize_text_field( $args['id'] ) : 'uds-feedback-form--wrapper';
90
91 // Return if not on the allowed screen.
92 if ( ! BSF_Analytics_Helper::is_allowed_screen() ) {
93 return;
94 }
95
96 // Product slug used for input fields and labels in each plugin's deactivation survey.
97 $product_slug = isset( $args['plugin_slug'] ) ? sanitize_text_field( $args['plugin_slug'] ) : 'bsf';
98
99 ?>
100 <div id="<?php echo esc_attr( $id ); ?>" class="uds-feedback-form--wrapper" style="display: none">
101 <div class="uds-feedback-form--container">
102 <div class="uds-form-header--wrapper">
103 <div class="uds-form-title--icon-wrapper">
104 <?php if ( ! empty( $args['popup_logo'] ) ) { ?>
105 <img class="uds-icon" src="<?php echo esc_url( $args['popup_logo'] ); ?>" title="<?php echo esc_attr( $args['plugin_slug'] ); ?> <?php echo esc_attr( __( 'Icon' ) ); ?>" />
106 <?php } ?>
107 <h2 class="uds-title"><?php echo esc_html( $args['popup_title'] ); ?></h2>
108 </div>
109 <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="uds-close">
110 <path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
111 </svg>
112 </div>
113 <div class="uds-form-body--content">
114
115 <?php if ( ! empty( $args['popup_description'] ) ) { ?>
116 <p class="uds-form-description"><?php echo esc_html( $args['popup_description'] ); ?></p>
117 <?php } ?>
118
119 <form class="uds-feedback-form" id="uds-feedback-form" method="post">
120 <?php foreach ( $args['popup_reasons'] as $key => $value ) {
121 $input_id = $product_slug . '_uds_reason_input_' . $key;
122 ?>
123 <fieldset>
124 <div class="reason">
125 <input type="radio" class="uds-reason-input" name="uds_reason_input" id="<?php echo esc_attr( $input_id ); ?>" value="<?php echo esc_attr( $key ); ?>" data-placeholder="<?php echo esc_attr( $value['placeholder'] ); ?>" data-show_cta="<?php echo esc_attr( $value['show_cta'] ); ?>" data-accept_feedback="<?php echo esc_attr( $value['accept_feedback'] ); ?>">
126 <label class="uds-reason-label" for="<?php echo esc_attr( $input_id ); ?>"><?php echo esc_html( $value['label'] ); ?></label>
127 </div>
128 </fieldset>
129 <?php } ?>
130
131 <fieldset>
132 <textarea class="uds-options-feedback hide" id="uds-options-feedback" rows="3" name="uds_options_feedback" placeholder="<?php echo esc_attr( __( 'Please tell us more details.' ) ); ?>"></textarea>
133 <?php
134 if ( ! empty( $args['support_url'] ) ) {
135 ?>
136 <p class="uds-option-feedback-cta hide">
137 <?php
138 echo wp_kses_post(
139 sprintf(
140 /* translators: %1$s: link html start, %2$s: link html end*/
141 __( 'Need help from our experts? %1$sClick here to contact us.%2$s' ),
142 '<a href="' . esc_url( $args['support_url'] ) . '" target="_blank">',
143 '</a>'
144 )
145 );
146 ?>
147 </p>
148 <?php } ?>
149 </fieldset>
150
151 <div class="uds-feedback-form-sumbit--actions">
152 <button class="button button-primary uds-feedback-submit" data-action="submit"><?php esc_html_e( 'Submit & Deactivate' ); ?></button>
153 <button class="button button-secondary uds-feedback-skip" data-action="skip"><?php esc_html_e( 'Skip & Deactivate' ); ?></button>
154 <input type="hidden" name="referer" value="<?php echo esc_url( get_site_url() ); ?>">
155 <input type="hidden" name="version" value="<?php echo esc_attr( $args['plugin_version'] ); ?>">
156 <input type="hidden" name="source" value="<?php echo esc_attr( $args['plugin_slug'] ); ?>">
157 </div>
158 </form>
159 </div>
160
161 </div>
162 </div>
163 <?php
164 }
165
166 /**
167 * Load form styles.
168 *
169 * This function loads the necessary styles for the feedback form.
170 *
171 * @since 1.1.6
172 * @return void
173 */
174 public static function load_form_styles() {
175
176 if ( ! BSF_Analytics_Helper::is_allowed_screen() ) {
177 return;
178 }
179
180 $dir_path = BSF_ANALYTICS_URI . '/modules/deactivation-survey/';
181 $file_ext = ! SCRIPT_DEBUG ? '.min' : '';
182
183 wp_enqueue_script(
184 'uds-feedback-script',
185 $dir_path . 'assets/js/feedback' . $file_ext . '.js',
186 array( 'jquery' ),
187 BSF_ANALYTICS_VERSION,
188 true
189 );
190
191 $data = apply_filters(
192 'uds_survey_vars',
193 array(
194 'ajaxurl' => esc_url( admin_url( 'admin-ajax.php' ) ),
195 '_ajax_nonce' => wp_create_nonce( 'uds_plugin_deactivate_feedback' ),
196 '_current_theme' => function_exists( 'wp_get_theme' ) ? wp_get_theme()->get_template() : '',
197 '_plugin_slug' => array(),
198 )
199 );
200
201 // Add localize JS.
202 wp_localize_script(
203 'uds-feedback-script',
204 'udsVars',
205 $data
206 );
207
208 wp_enqueue_style( 'uds-feedback-style', $dir_path . 'assets/css/feedback' . $file_ext . '.css', array(), BSF_ANALYTICS_VERSION );
209 wp_style_add_data( 'uds-feedback-style', 'rtl', 'replace' );
210 wp_style_add_data( 'uds-feedback-style', 'suffix', $file_ext );
211 }
212
213 /**
214 * Sends plugin deactivation feedback to the server.
215 *
216 * This function checks the user's permission and verifies the nonce for the request.
217 * If the checks pass, it sends the feedback data to the server for processing.
218 *
219 * @return void
220 */
221 public function send_plugin_deactivate_feedback() {
222
223 $response_data = array( 'message' => __( 'Sorry, you are not allowed to do this operation.' ) );
224
225 /**
226 * Check permission
227 */
228 if ( ! current_user_can( 'manage_options' ) ) {
229 wp_send_json_error( $response_data );
230 }
231
232 /**
233 * Nonce verification
234 */
235 if ( ! check_ajax_referer( 'uds_plugin_deactivate_feedback', 'security', false ) ) {
236 $response_data = array( 'message' => __( 'Nonce validation failed' ) );
237 wp_send_json_error( $response_data );
238 }
239
240 $feedback_data = array(
241 'reason' => isset( $_POST['reason'] ) ? sanitize_text_field( wp_unslash( $_POST['reason'] ) ) : '',
242 'feedback' => isset( $_POST['feedback'] ) ? sanitize_text_field( wp_unslash( $_POST['feedback'] ) ) : '',
243 'domain_name' => isset( $_POST['referer'] ) ? sanitize_text_field( wp_unslash( $_POST['referer'] ) ) : '',
244 'version' => isset( $_POST['version'] ) ? sanitize_text_field( wp_unslash( $_POST['version'] ) ) : '',
245 'plugin' => isset( $_POST['source'] ) ? sanitize_text_field( wp_unslash( $_POST['source'] ) ) : '',
246 );
247
248 $api_args = array(
249 'body' => wp_json_encode( $feedback_data ),
250 'headers' => BSF_Analytics_Helper::get_api_headers(),
251 'timeout' => 15, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
252 );
253
254 $target_url = BSF_Analytics_Helper::get_api_url() . self::$feedback_api_endpoint;
255
256 $response = wp_safe_remote_post( $target_url, $api_args );
257
258 $has_errors = BSF_Analytics_Helper::is_api_error( $response );
259
260 if ( $has_errors['error'] ) {
261 wp_send_json_error(
262 array(
263 'success' => false,
264 'message' => $has_errors['error_message'],
265 )
266 );
267 }
268
269 wp_send_json_success();
270 }
271
272 /**
273 * Get the array of default reasons.
274 *
275 * @return array Default reasons.
276 */
277 public static function get_default_reasons() {
278
279 return apply_filters(
280 'uds_default_deactivation_reasons',
281 array(
282 'temporary_deactivation' => array(
283 'label' => esc_html__( 'This is a temporary deactivation for testing.' ),
284 'placeholder' => esc_html__( 'How can we assist you?' ),
285 'show_cta' => 'false',
286 'accept_feedback' => 'false',
287 ),
288 'plugin_not_working' => array(
289 'label' => esc_html__( 'The plugin isn\'t working properly.' ),
290 'placeholder' => esc_html__( 'Please tell us more about what went wrong?' ),
291 'show_cta' => 'true',
292 'accept_feedback' => 'true',
293 ),
294 'found_better_plugin' => array(
295 'label' => esc_html__( 'I found a better alternative plugin.' ),
296 'placeholder' => esc_html__( 'Could you please specify which plugin?' ),
297 'show_cta' => 'false',
298 'accept_feedback' => 'true',
299 ),
300 'missing_a_feature' => array(
301 'label' => esc_html__( 'It\'s missing a specific feature.' ),
302 'placeholder' => esc_html__( 'Please tell us more about the feature.' ),
303 'show_cta' => 'false',
304 'accept_feedback' => 'true',
305 ),
306 'other' => array(
307 'label' => esc_html__( 'Other' ),
308 'placeholder' => esc_html__( 'Please tell us more details.' ),
309 'show_cta' => 'false',
310 'accept_feedback' => 'true',
311 ),
312 )
313 );
314 }
315 }
316
317 Deactivation_Survey_Feedback::get_instance();
318 }
319