latepoint
/
lib
/
kit
/
bsf-analytics
/
modules
/
deactivation-survey
/
classes
/
class-deactivation-survey-feedback.php
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 |