$attributes Block attributes. * @since 0.0.2 */ public function __construct( $attributes ) { $this->set_properties( $attributes ); $this->set_input_label( __( 'Phone', 'sureforms' ) ); $this->set_error_msg( $attributes, 'srfm_phone_block_required_text' ); $this->set_duplicate_msg( $attributes, 'srfm_phone_block_unique_text' ); $this->slug = 'phone'; $this->auto_country = $attributes['autoCountry'] ?? ''; $this->default_country = $attributes['defaultCountry'] ?? ''; $this->enable_country_filter = $attributes['enableCountryFilter'] ?? false; $this->country_filter_type = $attributes['countryFilterType'] ?? 'include'; $this->include_countries = $attributes['includeCountries'] ?? []; $this->exclude_countries = $attributes['excludeCountries'] ?? []; // When auto country is enabled, detect the visitor's country via server-side // IP geolocation (ipapi.co) instead of a client-side fetch. // // Why not get_locale()? // WordPress get_locale() returns the *site's* configured language (e.g. 'en_US'), // not the visitor's physical location. A site set to English would show 'US' for // every visitor worldwide — defeating the purpose of auto-country detection. // // Why server-side instead of client-side? // The previous client-side fetch('https://ipapi.co/json') caused CORS failures, // 429 rate limits on high-traffic sites, and exposed visitor IPs to a third party // directly from the browser. Moving it server-side eliminates all three issues. // // Performance: The API is called only once per visitor IP and cached in a transient // for 24 hours — subsequent page loads for the same IP resolve instantly from cache. if ( $this->auto_country ) { $this->default_country = $this->get_geo_country(); } $this->set_unique_slug(); $this->set_field_name( $this->unique_slug ); $this->set_markup_properties( $this->input_label, true ); $this->set_aria_described_by(); $this->set_label_as_placeholder( $this->input_label ); } /** * Render the sureforms phone classic styling * * @since 0.0.2 * @return string|bool */ public function markup() { ob_start(); ?>
label_markup ); ?> help_markup ); ?>
aria_described_by ) ? "aria-describedby='" . esc_attr( trim( $this->aria_described_by ) ) . "'" : ''; ?> data-required="data_require_attr ); ?>" aria-required="data_require_attr ); ?>" default-country="default_country ); ?>" enable_country_filter ) { ?> data-enable-country-filter="true" data-country-filter-type="country_filter_type ); ?>" country_filter_type && ! empty( $this->include_countries ) ) { ?> data-include-countries="include_countries ) ) ); ?>" country_filter_type && ! empty( $this->exclude_countries ) ) { ?> data-exclude-countries="exclude_countries ) ) ); ?>" value="default ); ?>" placeholder_attr ); ?> data-unique="aria_unique ); ?>">
duplicate_msg_markup ); ?>
= $quota_cap ) { set_transient( $cache_key, 'us', HOUR_IN_SECONDS ); return 'us'; } set_transient( $quota_key, $count + 1, HOUR_IN_SECONDS ); // ipapi.co's /json/ endpoint geolocates the *caller's* IP. Since this request // originates from the WordPress server (not the visitor's browser), we must // pass the visitor's IP explicitly via /{ip}/json/ — otherwise ipapi.co // returns the hosting datacenter's country for every visitor. $url = 'https://ipapi.co/' . rawurlencode( $ip ) . '/json/'; $response = wp_remote_get( $url, [ 'timeout' => 3, 'user-agent' => 'SureForms/' . SRFM_VER . ' (+https://sureforms.com)', ] ); if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) { set_transient( $cache_key, 'us', HOUR_IN_SECONDS ); return 'us'; } $body = json_decode( wp_remote_retrieve_body( $response ), true ); if ( ! is_array( $body ) || empty( $body['country_code'] ) || ! is_string( $body['country_code'] ) ) { set_transient( $cache_key, 'us', HOUR_IN_SECONDS ); return 'us'; } $country = strtolower( $body['country_code'] ); // Validate the external API response is a valid 2-letter country code. if ( ! preg_match( '/^[a-z]{2}$/', $country ) ) { set_transient( $cache_key, 'us', HOUR_IN_SECONDS ); return 'us'; } set_transient( $cache_key, $country, DAY_IN_SECONDS ); return $country; } }