PluginProbe ʕ •ᴥ•ʔ
Appointment Booking Plugin – LatePoint | Calendar & Scheduling for WordPress / 5.6.1
Appointment Booking Plugin – LatePoint | Calendar & Scheduling for WordPress v5.6.1
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 4 months ago
class-deactivation-survey-feedback.php
318 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 }
211
212 /**
213 * Sends plugin deactivation feedback to the server.
214 *
215 * This function checks the user's permission and verifies the nonce for the request.
216 * If the checks pass, it sends the feedback data to the server for processing.
217 *
218 * @return void
219 */
220 public function send_plugin_deactivate_feedback() {
221
222 $response_data = array( 'message' => __( 'Sorry, you are not allowed to do this operation.' ) );
223
224 /**
225 * Check permission
226 */
227 if ( ! current_user_can( 'manage_options' ) ) {
228 wp_send_json_error( $response_data );
229 }
230
231 /**
232 * Nonce verification
233 */
234 if ( ! check_ajax_referer( 'uds_plugin_deactivate_feedback', 'security', false ) ) {
235 $response_data = array( 'message' => __( 'Nonce validation failed' ) );
236 wp_send_json_error( $response_data );
237 }
238
239 $feedback_data = array(
240 'reason' => isset( $_POST['reason'] ) ? sanitize_text_field( wp_unslash( $_POST['reason'] ) ) : '',
241 'feedback' => isset( $_POST['feedback'] ) ? sanitize_text_field( wp_unslash( $_POST['feedback'] ) ) : '',
242 'domain_name' => isset( $_POST['referer'] ) ? sanitize_text_field( wp_unslash( $_POST['referer'] ) ) : '',
243 'version' => isset( $_POST['version'] ) ? sanitize_text_field( wp_unslash( $_POST['version'] ) ) : '',
244 'plugin' => isset( $_POST['source'] ) ? sanitize_text_field( wp_unslash( $_POST['source'] ) ) : '',
245 );
246
247 $api_args = array(
248 'body' => wp_json_encode( $feedback_data ),
249 'headers' => BSF_Analytics_Helper::get_api_headers(),
250 'timeout' => 15, //phpcs:ignore WordPressVIPMinimum.Performance.RemoteRequestTimeout.timeout_timeout
251 );
252
253 $target_url = BSF_Analytics_Helper::get_api_url() . self::$feedback_api_endpoint;
254
255 $response = wp_safe_remote_post( $target_url, $api_args );
256
257 $has_errors = BSF_Analytics_Helper::is_api_error( $response );
258
259 if ( $has_errors['error'] ) {
260 wp_send_json_error(
261 array(
262 'success' => false,
263 'message' => $has_errors['error_message'],
264 )
265 );
266 }
267
268 wp_send_json_success();
269 }
270
271 /**
272 * Get the array of default reasons.
273 *
274 * @return array Default reasons.
275 */
276 public static function get_default_reasons() {
277
278 return apply_filters(
279 'uds_default_deactivation_reasons',
280 array(
281 'temporary_deactivation' => array(
282 'label' => esc_html__( 'This is a temporary deactivation for testing.' ),
283 'placeholder' => esc_html__( 'How can we assist you?' ),
284 'show_cta' => 'false',
285 'accept_feedback' => 'false',
286 ),
287 'plugin_not_working' => array(
288 'label' => esc_html__( 'The plugin isn\'t working properly.' ),
289 'placeholder' => esc_html__( 'Please tell us more about what went wrong?' ),
290 'show_cta' => 'true',
291 'accept_feedback' => 'true',
292 ),
293 'found_better_plugin' => array(
294 'label' => esc_html__( 'I found a better alternative plugin.' ),
295 'placeholder' => esc_html__( 'Could you please specify which plugin?' ),
296 'show_cta' => 'false',
297 'accept_feedback' => 'true',
298 ),
299 'missing_a_feature' => array(
300 'label' => esc_html__( 'It\'s missing a specific feature.' ),
301 'placeholder' => esc_html__( 'Please tell us more about the feature.' ),
302 'show_cta' => 'false',
303 'accept_feedback' => 'true',
304 ),
305 'other' => array(
306 'label' => esc_html__( 'Other' ),
307 'placeholder' => esc_html__( 'Please tell us more details.' ),
308 'show_cta' => 'false',
309 'accept_feedback' => 'true',
310 ),
311 )
312 );
313 }
314 }
315
316 Deactivation_Survey_Feedback::get_instance();
317 }
318