admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'eppro_deactivate_feedback' ), 'pluginFile' => EPPRO_BASENAME, 'i18n' => [ 'title' => __( "We'd love your feedback", 'admore-widgets-suite' ), 'subtitle' => __( 'Quick question before you go — why are you deactivating Essential Pro Pack?', 'admore-widgets-suite' ), 'submit' => __( 'Submit & Deactivate', 'admore-widgets-suite' ), 'skip' => __( 'Skip & Deactivate', 'admore-widgets-suite' ), 'cancel' => __( 'Cancel', 'admore-widgets-suite' ), 'placeholder' => __( 'Please share more details (optional)…', 'admore-widgets-suite' ), 'submitting' => __( 'Sending…', 'admore-widgets-suite' ), 'thanks' => __( 'Thank you for your feedback!', 'admore-widgets-suite' ), 'reasons' => [ 'missing_features' => __( 'Missing features I need', 'admore-widgets-suite' ), 'found_bug' => __( 'Found a bug or issue', 'admore-widgets-suite' ), 'plugin_slow' => __( 'Plugin is slow', 'admore-widgets-suite' ), 'not_needed' => __( 'No longer needed', 'admore-widgets-suite' ), 'switching' => __( 'Switching to another plugin','admore-widgets-suite' ), 'temporary' => __( 'Temporary deactivation', 'admore-widgets-suite' ), 'other' => __( 'Other reason', 'admore-widgets-suite' ), ], ], ] ); } // ========================================================================= // AJAX: Dismiss Install Notice // ========================================================================= public static function ajax_dismiss_notice(): void { check_ajax_referer( 'eppro_dismiss_notice', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( null, 403 ); } update_option( self::OPT_DISMISSED, '1', false ); delete_option( self::OPT_SHOW_NOTICE ); wp_send_json_success(); } // ========================================================================= // AJAX: Submit Deactivation Feedback // ========================================================================= public static function ajax_submit_feedback(): void { check_ajax_referer( 'eppro_deactivate_feedback', 'nonce' ); if ( ! current_user_can( 'activate_plugins' ) ) { wp_send_json_error( [ 'message' => __( 'Insufficient permissions.', 'admore-widgets-suite' ) ], 403 ); } $allowed_reasons = [ 'missing_features', 'found_bug', 'plugin_slow', 'not_needed', 'switching', 'temporary', 'other', ]; $reason = sanitize_key( wp_unslash( $_POST['reason'] ?? '' ) ); $details = sanitize_textarea_field( wp_unslash( $_POST['details'] ?? '' ) ); if ( ! in_array( $reason, $allowed_reasons, true ) ) { wp_send_json_error( [ 'message' => __( 'Invalid reason.', 'admore-widgets-suite' ) ] ); } $entry = [ 'reason' => $reason, 'details' => $details, 'site_url' => esc_url_raw( home_url() ), 'wp_version' => get_bloginfo( 'version' ), 'eppro_version' => EPPRO_VERSION, 'timestamp' => current_time( 'mysql' ), 'user_id' => get_current_user_id(), ]; // Append to local log (last 50 entries) $log = get_option( self::OPT_FEEDBACK_LOG, [] ); if ( ! is_array( $log ) ) $log = []; array_unshift( $log, $entry ); $log = array_slice( $log, 0, 50 ); update_option( self::OPT_FEEDBACK_LOG, $log, false ); // Optional webhook if ( ! empty( self::WEBHOOK_URL ) ) { self::dispatch_webhook( $entry ); } wp_send_json_success(); } // ========================================================================= // Webhook Dispatch // ========================================================================= private static function dispatch_webhook( array $entry ): void { $url = esc_url_raw( self::WEBHOOK_URL ); if ( empty( $url ) ) return; wp_remote_post( $url, [ 'body' => wp_json_encode( $entry ), 'headers' => [ 'Content-Type' => 'application/json' ], 'timeout' => 8, 'blocking' => false, 'data_format' => 'body', ] ); } }