* @since 1.0.0 */ public function get_user_details() { $details = Helper::get_suredonation_option( self::USER_DETAILS_KEY, [] ); return is_array( $details ) ? $details : []; } /** * Persist the lead-capture payload. * * @param array $details Raw payload (already sanitised). * @return void * @since 1.0.0 */ public function set_user_details( array $details ) { Helper::update_suredonation_option( self::USER_DETAILS_KEY, $details ); } /** * On the first admin pageload after activation, send the admin to the * onboarding screen — but only if onboarding isn't already done. * * @return void * @since 1.0.0 */ public function maybe_redirect_to_onboarding() { if ( wp_doing_ajax() || wp_doing_cron() ) { return; } // admin_init fires for REST and network-admin contexts too — neither // should ever 302 to the onboarding screen. if ( ( defined( 'REST_REQUEST' ) && REST_REQUEST ) || is_network_admin() ) { return; } // Only honour the redirect on the initial GET that lands the admin // on a wp-admin page — a POST hitting admin_init would otherwise // 302 mid-form-submission. if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'GET' !== strtoupper( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_METHOD'] ) ) ) ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reading a flag, not processing form input. if ( isset( $_GET['activate-multi'] ) ) { return; } if ( ! get_option( self::REDIRECT_FLAG ) ) { return; } // One-shot — drop the row entirely so the option table doesn't // accumulate dead flags. The activation hook will recreate it on // the next plugin activation. delete_option( self::REDIRECT_FLAG ); if ( ! current_user_can( 'manage_options' ) ) { return; } if ( $this->is_completed() ) { return; } wp_safe_redirect( admin_url( 'admin.php?page=' . self::PAGE_SLUG ) ); exit; } }