includes(); $this->init_hooks(); } protected function includes() { } protected function init_hooks() { // Add settings page add_action( 'admin_menu', array( $this, 'settings_page_menu' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts' ) ); // Tabs add_action( 'admin_init', array( $this, 'set_tabs' ) ); add_action( 'wps_aa_options_tab_instances', array( $this, 'instances_tab' ) ); add_action( 'wps_aa_options_tab_settings', array( $this, 'settings_tab' ) ); // Save settings add_action( 'admin_init', array( $this, 'save_options' ) ); add_action( 'admin_notices', array( $this, 'show_notices' ), 999 ); // Google key test add_action( 'admin_post_wps_aa_key_test', array( $this, 'key_test_page' ) ); // Header links add_action( 'wps_aa_header_links', array( $this, 'header_links' ) ); } public function settings_page_menu() { add_options_page( __( 'Address Autocomplete', 'address-autocomplete-anything' ), __( 'Address Autocomplete', 'address-autocomplete-anything' ), 'manage_options', 'wps_aa', array( $this, 'options_page' ) ); } public function admin_enqueue_scripts() { if ( ! isset( $_GET['page'] ) || $_GET['page'] != 'wps_aa' ) { return; } wp_enqueue_style( 'wps-aa-admin', WPS_AA_URL . 'assets/css/admin.css', array(), WPS_AA_VERSION ); wp_enqueue_script( 'select2', WPS_AA_URL . 'assets/js/select2/select2.min.js', array( 'jquery' ), '4.0.13' ); wp_enqueue_style( 'select2', WPS_AA_URL . 'assets/js/select2/select2.min.css', array(), '4.0.13' ); wp_enqueue_script( 'wps-aa-admin', WPS_AA_URL . 'assets/js/admin.js', array( 'jquery', 'select2' ), WPS_AA_VERSION, true ); $components = array(); foreach ( WPS_AA()->get_available_place_components() as $component ) { $components[] = array( 'key' => $component['key'], 'label' => $component['label'], 'tag' => ! empty( $component['tag'] ) ? $component['tag'] : $component['label'], 'short_long' => ! isset( $component['short_long'] ), ); } wp_localize_script( 'wps-aa-admin', 'wps_aa_admin', array( 'components' => $components, 'picker_nonce' => wp_create_nonce( 'wps_aa_picker' ), 'home_url' => home_url( '/' ), 'key_test_url' => add_query_arg( array( 'action' => 'wps_aa_key_test', '_wpnonce' => wp_create_nonce( 'wps_aa_key_test' ), ), admin_url( 'admin-post.php' ) ), 'i18n' => array( 'insert' => __( 'Address data', 'address-autocomplete-anything' ), 'full' => __( 'Full', 'address-autocomplete-anything' ), 'short' => __( 'Short', 'address-autocomplete-anything' ), 'short_hint' => __( 'Short gives codes like "CA" or "US" instead of "California" or "United States".', 'address-autocomplete-anything' ), 'format' => __( 'Format', 'address-autocomplete-anything' ), 'fallback' => __( 'If empty, use', 'address-autocomplete-anything' ), 'fallback_none' => __( 'Add a backup…', 'address-autocomplete-anything' ), 'fallback_hint' => __( 'Tried in order when this part of the address is missing.', 'address-autocomplete-anything' ), 'before' => __( 'Text before', 'address-autocomplete-anything' ), 'after' => __( 'Text after', 'address-autocomplete-anything' ), 'before_hint' => __( 'Only added when there is a value, handy for commas and spaces.', 'address-autocomplete-anything' ), 'remove' => __( 'Remove', 'address-autocomplete-anything' ), 'done' => __( 'Done', 'address-autocomplete-anything' ), 'select_page' => __( 'All pages', 'address-autocomplete-anything' ), 'select_country' => __( 'All countries', 'address-autocomplete-anything' ), 'confirm_remove' => __( 'Remove this field?', 'address-autocomplete-anything' ), 'pick_choose' => __( 'Choose the page with your form first.', 'address-autocomplete-anything' ), 'pick_bad_url' => __( 'Use a link to a page on this site.', 'address-autocomplete-anything' ), 'pick_blocked' => __( 'Your browser blocked the new tab. Allow pop-ups for this site, then try again.', 'address-autocomplete-anything' ), 'pick_waiting' => __( 'Click the fields in the new tab, then Done.', 'address-autocomplete-anything' ), 'pick_replace' => __( 'Replace the fields in this setup with the ones you picked?', 'address-autocomplete-anything' ), 'pick_done' => __( 'Filled in from your page. Check the fields below, then save.', 'address-autocomplete-anything' ), 'key_empty' => __( 'Enter a key first.', 'address-autocomplete-anything' ), 'key_testing' => __( 'Testing your key with Google…', 'address-autocomplete-anything' ), 'key_timeout' => __( 'The test did not finish. Check your internet connection and try again.', 'address-autocomplete-anything' ), 'key_no_load' => __( 'Could not reach Google. Check your internet connection, or whether something on this site blocks Google\'s scripts.', 'address-autocomplete-anything' ), 'key_works' => __( 'Your key works with %s.', 'address-autocomplete-anything' ), 'key_switch' => __( 'Your key works with %1$s, not %2$s. Choose %1$s and save.', 'address-autocomplete-anything' ), 'key_new' => __( 'Places API (New)', 'address-autocomplete-anything' ), 'key_legacy' => __( 'Places API (Legacy)', 'address-autocomplete-anything' ), 'key_invalid' => __( 'Google does not recognize this key. Copy it again from Google Cloud.', 'address-autocomplete-anything' ), 'key_referer' => __( 'This key is not allowed on this website. In Google Cloud, add %s to the key\'s list of websites.', 'address-autocomplete-anything' ), 'key_billing' => __( 'Billing is not set up for your Google Cloud project. Google requires it, even if you stay within the free amount.', 'address-autocomplete-anything' ), 'key_maps_off' => __( 'The Maps JavaScript API is not turned on in your Google Cloud project.', 'address-autocomplete-anything' ), 'key_maps_block' => __( 'Your key is limited to certain APIs, and the Maps JavaScript API is not one of them.', 'address-autocomplete-anything' ), 'key_places_off' => __( '%s is not turned on in your Google Cloud project.', 'address-autocomplete-anything' ), 'key_places_block' => __( 'Your key is limited to certain APIs, and %s is not one of them.', 'address-autocomplete-anything' ), 'key_legacy_new' => __( 'Google stopped letting new projects turn on the legacy version in March 2025, so Places API (New) is usually the one to use.', 'address-autocomplete-anything' ), 'key_google_said' => __( 'Google said: %s', 'address-autocomplete-anything' ), ), ) ); } public function set_tabs() { $this->tabs = apply_filters( 'wps_aa_tabs', array( 'instances' => __( 'Instances', 'address-autocomplete-anything' ), 'settings' => __( 'Settings', 'address-autocomplete-anything' ), ) ); $this->tab = array_key_first( $this->tabs ); if ( isset( $_GET['tab'] ) ) { $this->tab = sanitize_key( $_GET['tab'] ); } // Instances used to live on the settings tab, so older links still land on them if ( $this->tab == 'settings' && isset( $_GET['instance'] ) ) { $this->tab = 'instances'; } } public function header_links( $links ) { $links = array( 'documentation' => array( 'url' => 'https://wpsunshine.com/support/', 'label' => 'Documentation', ), 'review' => array( 'url' => 'https://wordpress.org/support/plugin/address-autocomplete-anything/reviews/#new-post', 'label' => 'Write a Review', ), 'feedback' => array( 'url' => 'https://wpsunshine.com/feedback', 'label' => 'Feedback', ), 'upgrade' => array( 'url' => 'https://wpsunshine.com/plugins/address-autocomplete/?utm_source=plugin&utm_medium=banner&utm_content=upgrade&utm_campaign=aa_upgrade', 'label' => 'Upgrade', ), ); return $links; } /** * Whether this site can use premium features right now. */ public static function is_premium() { return function_exists( 'wps_aa_is_premium' ) && wps_aa_is_premium(); } public function options_page() { if ( isset( $_GET['wps_aa_setup'] ) ) { do_action( 'wps_aa_setup_page' ); return; } $options = WPS_AA()->get_options( true ); ?>
'; foreach ( $header_links as $key => $link ) { echo '' . esc_html( $link['label'] ) . ''; } echo '
'; } ?> tabs ) > 1 ) { ?>

tab ); if ( $this->tab == 'instances' && ! empty( $this->get_active_instance() ) ) { $form_url = add_query_arg( 'instance', $this->get_active_instance(), $form_url ); } ?>
tab ); ?> tab ); ?> tab ); ?>
'', 'collapsible' => false, 'open' => true, 'intro' => '', ) ); $open = ! $args['collapsible'] || $args['open']; $classes = 'wps-panel'; if ( $args['collapsible'] ) { $classes .= ' wps-panel--collapsible'; } if ( $args['collapsible'] && $open ) { $classes .= ' is-open'; } // A collapsible head is the control that opens the panel, so it has to // be a real button rather than a div with a click handler on it. $head_tag = $args['collapsible'] ? 'button' : 'div'; $head_attr = $args['collapsible'] ? ' type="button" class="wps-panel__head wps-panel__toggle" aria-expanded="' . ( $open ? 'true' : 'false' ) . '"' : ' class="wps-panel__head"'; ?>
<>

>
'; } /** * Open one option row: label on the left, control on the right. * * @param string $label Row label. * @param string $for ID of the control the label belongs to. */ public static function option_row_open( $label, $for = '' ) { ?>
' . wp_kses_post( $description ) . '

'; } echo '
'; } /** * A "Learn more" style link to a doc on wpsunshine.com. * * @param string $slug Doc slug. * @param string $label Link text. */ public static function doc_link( $slug, $label = '' ) { if ( ! $label ) { $label = __( 'Learn more', 'address-autocomplete-anything' ); } return '' . esc_html( $label ) . ''; } /** * The save button, and when this was last saved. * * @param int $updated Timestamp of the last save, if known. */ public static function save_bar( $updated = 0 ) { ?>
active_instance ) ) { $instances = WPS_AA()->get_instances(); $this->active_instance = ( isset( $_GET['instance'] ) && isset( $instances[ $_GET['instance'] ] ) ) ? sanitize_text_field( $_GET['instance'] ) : array_key_first( (array) $instances ); } return $this->active_instance; } public function settings_tab() { $lang = get_option( 'wps_aa_language' ); $places_api = ( get_option( 'wps_aa_places_api' ) === 'legacy' ) ? 'legacy' : 'new'; ?>
panel_open( 'google', __( 'Google', 'address-autocomplete-anything' ) ); $this->option_row_open( __( 'Google Maps API Key', 'address-autocomplete-anything' ), 'wps-aa-google-api-key' ); ?>
key_test_button(); ?>
option_row_close( $this->doc_link( 'google-maps-api-key', __( 'How to get a Google Maps API key', 'address-autocomplete-anything' ) ) ); $this->option_row_open( __( 'Places API version', 'address-autocomplete-anything' ) ); $this->places_api_choices( $places_api ); $this->option_row_close( __( 'Choose the version turned on for your Google API key.', 'address-autocomplete-anything' ) . ' ' . $this->doc_link( 'google-places-api-legacy-vs-new' ) ); $this->panel_close(); $this->panel_open( 'results', __( 'Address suggestions', 'address-autocomplete-anything' ) ); $this->option_row_open( __( 'Language', 'address-autocomplete-anything' ), 'wps-aa-language' ); ?> option_row_close( __( 'The language addresses are shown in.', 'address-autocomplete-anything' ) . ' ' . $this->doc_link( 'change-address-autocomplete-results-language' ) ); $this->option_row_open( __( 'List heading', 'address-autocomplete-anything' ), 'wps-aa-results-title' ); ?> option_row_close( __( 'Optional text shown at the top of the list of suggested addresses.', 'address-autocomplete-anything' ) . ' ' . $this->doc_link( 'address-autocomplete-results-title' ) ); $this->panel_close(); $this->save_bar(); ?>

array( 'label' => __( 'Places API (New)', 'address-autocomplete-anything' ), 'blurb' => __( 'Any project, including ones created recently.', 'address-autocomplete-anything' ), ), 'legacy' => array( 'label' => __( 'Places API (Legacy)', 'address-autocomplete-anything' ), 'blurb' => __( 'Google Cloud projects that had it turned on before March 2025.', 'address-autocomplete-anything' ), ), ); echo '
'; foreach ( $choices as $value => $choice ) { ?> '; } /** * Button that tests the key typed in the field. admin.js runs the test and * shows the result in the paragraph below it. Shared with the setup wizard. */ public static function key_test_button() { ?>

<?php esc_html_e( 'Google key test', 'address-autocomplete-anything' ); ?> get_instances(); $key = $this->get_active_instance(); if ( empty( $instances[ $key ] ) ) { return; } $instance = wp_parse_args( $instances[ $key ], array( 'label' => '', 'page' => array(), 'init' => '', 'allowed_countries' => array(), 'fields' => array(), 'delay' => '', 'updated' => 0, ) ); $this->instance_nav( $instances, $key ); do_action( 'wps_aa_instance_before', $key, $instance ); ?>
panel_open( 'address-field', __( 'Address field', 'address-autocomplete-anything' ), array( 'intro' => __( 'The field people type their address into. Suggestions from Google show up under it.', 'address-autocomplete-anything' ) ) ); // Instances an integration sets up already know their fields $pickable = apply_filters( 'wps_aa_instance_pickable', true, $key ); ?>

doc_link( 'finding-your-css-selectors', __( 'How to find it', 'address-autocomplete-anything' ) ); // phpcs:ignore ?>

picker_start( $instance['page'] ); ?>

panel_close(); $this->panel_open( 'fill-fields', __( 'Fill in these fields', 'address-autocomplete-anything' ), array( 'intro' => __( 'When someone picks an address, each field below gets filled in. Type any text you like and use + Address data to add parts of the address.', 'address-autocomplete-anything' ) ) ); $this->fields_editor( $instance['fields'] ); $this->panel_close(); $this->panel_open( 'where', __( 'Where it runs', 'address-autocomplete-anything' ), array( 'collapsible' => true, 'open' => ! empty( $instance['allowed_countries'] ) || ! empty( array_filter( (array) $instance['page'] ) ) || ! empty( $instance['delay'] ), ) ); $this->option_row_open( __( 'Countries', 'address-autocomplete-anything' ), 'wps-aa-countries' ); ?> option_row_close( __( 'Only suggest addresses in these countries. Leave empty for everywhere.', 'address-autocomplete-anything' ) . ' ' . $this->doc_link( 'restrict-address-autocomplete-to-specific-countries' ) ); $this->option_row_open( __( 'Pages', 'address-autocomplete-anything' ), 'wps-aa-pages' ); ?> option_row_close( __( 'Only load on these pages, so the rest of your site stays lighter. Leave empty for every page.', 'address-autocomplete-anything' ) . ' ' . $this->doc_link( 'restrict-address-autocomplete-to-specific-pages' ) ); $this->option_row_open( __( 'Start delay', 'address-autocomplete-anything' ), 'wps-aa-delay' ); ?> option_row_close( __( 'Wait before starting, for forms that appear after the page loads.', 'address-autocomplete-anything' ) . ' ' . $this->doc_link( 'address-autocomplete-load-delay-option' ) ); $this->panel_close(); $this->save_bar( $instance['updated'] ); ?>

$instance ) { $i++; $names[ $key ] = ! empty( $instance['label'] ) ? $instance['label'] : sprintf( __( 'Instance #%s', 'address-autocomplete-anything' ), $i ); } ?>
max_instances() ) : ?>
field_row( $i, $field ); $i++; } ?>

doc_link( 'available-address-fields-for-data-population', __( 'What each part of the address means', 'address-autocomplete-anything' ) ); // phpcs:ignore ?> · doc_link( 'address-autocomplete-fallback-values', __( 'Backup values', 'address-autocomplete-anything' ) ); // phpcs:ignore ?> · doc_link( 'before-and-after-attributes', __( 'Text before and after', 'address-autocomplete-anything' ) ); // phpcs:ignore ?>

'', 'data' => '', 'delay' => '', ) ); ?>
ms
get_instances(); $saved = get_option( 'wps_aa_instances' ); $saved = is_array( $saved ) ? $saved : array(); $instances = array(); foreach ( $available_instances as $key => $instance ) { // Instances not being edited stay as they were saved. Ones an integration // builds are left out until someone changes them, so they keep following // the integration's defaults. if ( empty( $_POST['instance'] ) || $_POST['instance'] != $key ) { if ( isset( $saved[ $key ] ) ) { $instances[ $key ] = $saved[ $key ]; } continue; } $fields = array(); foreach ( ( isset( $_POST['fields'] ) ? (array) $_POST['fields'] : array() ) as $field ) { if ( empty( $field['selector'] ) ) { continue; } $fields[] = array( 'selector' => isset( $field['selector'] ) ? sanitize_text_field( stripslashes( $field['selector'] ) ) : '', 'data' => isset( $field['data'] ) ? $this->sanitize_data_field( stripslashes( $field['data'] ) ) : '', 'delay' => isset( $field['delay'] ) && $field['delay'] !== '' ? floatval( $field['delay'] ) : '', ); } $instances[ $key ] = array( 'label' => isset( $_POST['label'] ) ? sanitize_text_field( stripslashes( $_POST['label'] ) ) : '', 'page' => isset( $_POST['allowed_page'] ) ? array_values( array_filter( array_map( 'intval', $_POST['allowed_page'] ) ) ) : '', 'init' => isset( $_POST['init'] ) ? sanitize_text_field( stripslashes( $_POST['init'] ) ) : '', 'allowed_countries' => ( ! empty( $_POST['allowed_countries'] ) ) ? array_map( 'sanitize_text_field', $_POST['allowed_countries'] ) : '', 'delay' => isset( $_POST['delay'] ) ? sanitize_text_field( $_POST['delay'] ) : '', 'fields' => $fields, 'updated' => time(), ); $this->active_instance = $key; } $instances = apply_filters( 'wps_aa_save_instances', $instances ); do_action( 'wps_aa_save_options' ); // If all valid if ( count( self::$errors ) > 0 ) { foreach ( self::$errors as $error ) { $this->add_notice( $error, 'error' ); } } update_option( 'wps_aa_instances', $instances ); if ( isset( $_POST['google_api_key'] ) ) { update_option( 'wps_aa_google_api_key', sanitize_text_field( $_POST['google_api_key'] ) ); } if ( isset( $_POST['places_api'] ) ) { update_option( 'wps_aa_places_api', ( $_POST['places_api'] === 'legacy' ) ? 'legacy' : 'new' ); } if ( isset( $_POST['language'] ) ) { update_option( 'wps_aa_language', sanitize_text_field( $_POST['language'] ) ); } if ( isset( $_POST['results_title'] ) ) { update_option( 'wps_aa_results_title', sanitize_text_field( stripslashes( $_POST['results_title'] ) ) ); } $this->add_notice( __( 'Settings saved!', 'address-autocomplete-anything' ) ); } public static function add_notice( $text, $type = 'success' ) { self::$notices[] = array( 'text' => $text, 'type' => $type, ); } /** * @param bool $in_setup True when called from inside the setup wizard card, * which is the only place notices show during setup. */ public static function show_notices( $in_setup = false ) { if ( isset( $_GET['wps_aa_setup'] ) && true !== $in_setup ) { return; } if ( ! empty( self::$notices ) ) { foreach ( self::$notices as $notice ) { echo '

' . wp_kses_post( $notice['text'] ) . '

'; } } } /** * Sanitize data field while preserving newlines from textarea. * * @param string $data The data field value. * @return string Sanitized data with newlines preserved. */ protected function sanitize_data_field( $data ) { // Preserve actual newlines from textarea $data = str_replace( "\r\n", '{{NEWLINE}}', $data ); $data = str_replace( "\n", '{{NEWLINE}}', $data ); // Use wp_kses to strip HTML and dangerous content $data = wp_kses( $data, array() ); // Restore newlines $data = str_replace( '{{NEWLINE}}', "\n", $data ); return $data; } private function languages() { return array( 'ar' => __( 'Arabic', 'address-autocomplete-anything' ), 'bg' => __( 'Bulgarian', 'address-autocomplete-anything' ), 'bn' => __( 'Bengali', 'address-autocomplete-anything' ), 'ca' => __( 'Catalan', 'address-autocomplete-anything' ), 'cs' => __( 'Czech', 'address-autocomplete-anything' ), 'da' => __( 'Danish', 'address-autocomplete-anything' ), 'de' => __( 'German', 'address-autocomplete-anything' ), 'el' => __( 'Greek', 'address-autocomplete-anything' ), 'en' => __( 'English', 'address-autocomplete-anything' ), 'en-AU' => __( 'English (Australian)', 'address-autocomplete-anything' ), 'en-GB' => __( 'English (Great Britain)', 'address-autocomplete-anything' ), 'es' => __( 'Spanish', 'address-autocomplete-anything' ), 'eu' => __( 'Basque', 'address-autocomplete-anything' ), 'fa' => __( 'Farsi', 'address-autocomplete-anything' ), 'fi' => __( 'Finnish', 'address-autocomplete-anything' ), 'fil' => __( 'Filipino', 'address-autocomplete-anything' ), 'fr' => __( 'French', 'address-autocomplete-anything' ), 'gl' => __( 'Galician', 'address-autocomplete-anything' ), 'gu' => __( 'Gujarati', 'address-autocomplete-anything' ), 'hi' => __( 'Hindi', 'address-autocomplete-anything' ), 'hr' => __( 'Croatian', 'address-autocomplete-anything' ), 'hu' => __( 'Hungarian', 'address-autocomplete-anything' ), 'id' => __( 'Indonesian', 'address-autocomplete-anything' ), 'it' => __( 'Italian', 'address-autocomplete-anything' ), 'iw' => __( 'Hebrew', 'address-autocomplete-anything' ), 'ja' => __( 'Japanese', 'address-autocomplete-anything' ), 'kn' => __( 'Kannada', 'address-autocomplete-anything' ), 'ko' => __( 'Korean', 'address-autocomplete-anything' ), 'lt' => __( 'Lithuanian', 'address-autocomplete-anything' ), 'lv' => __( 'Latvian', 'address-autocomplete-anything' ), 'ml' => __( 'Malayalam', 'address-autocomplete-anything' ), 'mr' => __( 'Marathi', 'address-autocomplete-anything' ), 'nl' => __( 'Dutch', 'address-autocomplete-anything' ), 'no' => __( 'Norwegian', 'address-autocomplete-anything' ), 'pl' => __( 'Polish', 'address-autocomplete-anything' ), 'pt' => __( 'Portuguese', 'address-autocomplete-anything' ), 'pt-BR' => __( 'Portuguese (Brazil)', 'address-autocomplete-anything' ), 'pt-PT' => __( 'Portuguese (Portugal)', 'address-autocomplete-anything' ), 'ro' => __( 'Romanian', 'address-autocomplete-anything' ), 'ru' => __( 'Russian', 'address-autocomplete-anything' ), 'sk' => __( 'Slovak', 'address-autocomplete-anything' ), 'sl' => __( 'Slovenian', 'address-autocomplete-anything' ), 'sr' => __( 'Serbian', 'address-autocomplete-anything' ), 'sv' => __( 'Swedish', 'address-autocomplete-anything' ), 'ta' => __( 'Tamil', 'address-autocomplete-anything' ), 'te' => __( 'Telugu', 'address-autocomplete-anything' ), 'th' => __( 'Thai', 'address-autocomplete-anything' ), 'tl' => __( 'Tagalog', 'address-autocomplete-anything' ), 'tr' => __( 'Turkish', 'address-autocomplete-anything' ), 'uk' => __( 'Ukrainian', 'address-autocomplete-anything' ), 'vi' => __( 'Vietnamese', 'address-autocomplete-anything' ), 'zh-CN' => __( 'Chinese (Simplified)', 'address-autocomplete-anything' ), 'zh-TW' => __( 'Chinese (Traditional)', 'address-autocomplete-anything' ), ); } private function countries() { return array( 'AF' => 'Afghanistan', 'AL' => 'Albania', 'DZ' => 'Algeria', 'AS' => 'American Samoa', 'AD' => 'Andorra', 'AO' => 'Angola', 'AI' => 'Anguilla', 'AQ' => 'Antarctica', 'AG' => 'Antigua and Barbuda', 'AR' => 'Argentina', 'AM' => 'Armenia', 'AW' => 'Aruba', 'AU' => 'Australia', 'AT' => 'Austria', 'AZ' => 'Azerbaijan', 'BS' => 'Bahamas', 'BH' => 'Bahrain', 'BD' => 'Bangladesh', 'BB' => 'Barbados', 'BY' => 'Belarus', 'BE' => 'Belgium', 'BZ' => 'Belize', 'BJ' => 'Benin', 'BM' => 'Bermuda', 'BT' => 'Bhutan', 'BO' => 'Bolivia', 'BA' => 'Bosnia and Herzegovina', 'BW' => 'Botswana', 'BV' => 'Bouvet Island', 'BR' => 'Brazil', 'IO' => 'British Indian Ocean Territory', 'BN' => 'Brunei Darussalam', 'BG' => 'Bulgaria', 'BF' => 'Burkina Faso', 'BI' => 'Burundi', 'KH' => 'Cambodia', 'CM' => 'Cameroon', 'CA' => 'Canada', 'CV' => 'Cape Verde', 'KY' => 'Cayman Islands', 'CF' => 'Central African Republic', 'TD' => 'Chad', 'CL' => 'Chile', 'CN' => 'China', 'CX' => 'Christmas Island', 'CC' => 'Cocos (Keeling) Islands', 'CO' => 'Colombia', 'KM' => 'Comoros', 'CG' => 'Congo', 'CD' => 'Congo, the Democratic Republic of the', 'CK' => 'Cook Islands', 'CR' => 'Costa Rica', 'CI' => "Cote D'Ivoire", 'HR' => 'Croatia', 'CU' => 'Cuba', 'CY' => 'Cyprus', 'CZ' => 'Czech Republic', 'DK' => 'Denmark', 'DJ' => 'Djibouti', 'DM' => 'Dominica', 'DO' => 'Dominican Republic', 'EC' => 'Ecuador', 'EG' => 'Egypt', 'SV' => 'El Salvador', 'GQ' => 'Equatorial Guinea', 'ER' => 'Eritrea', 'EE' => 'Estonia', 'ET' => 'Ethiopia', 'FK' => 'Falkland Islands (Malvinas)', 'FO' => 'Faroe Islands', 'FJ' => 'Fiji', 'FI' => 'Finland', 'FR' => 'France', 'GF' => 'French Guiana', 'PF' => 'French Polynesia', 'TF' => 'French Southern Territories', 'GA' => 'Gabon', 'GM' => 'Gambia', 'GE' => 'Georgia', 'DE' => 'Germany', 'GH' => 'Ghana', 'GI' => 'Gibraltar', 'GR' => 'Greece', 'GL' => 'Greenland', 'GD' => 'Grenada', 'GP' => 'Guadeloupe', 'GU' => 'Guam', 'GT' => 'Guatemala', 'GN' => 'Guinea', 'GW' => 'Guinea-Bissau', 'GY' => 'Guyana', 'HT' => 'Haiti', 'HM' => 'Heard Island and Mcdonald Islands', 'VA' => 'Holy See (Vatican City State)', 'HN' => 'Honduras', 'HK' => 'Hong Kong', 'HU' => 'Hungary', 'IS' => 'Iceland', 'IN' => 'India', 'ID' => 'Indonesia', 'IR' => 'Iran, Islamic Republic of', 'IQ' => 'Iraq', 'IE' => 'Ireland', 'IL' => 'Israel', 'IT' => 'Italy', 'JM' => 'Jamaica', 'JP' => 'Japan', 'JO' => 'Jordan', 'KZ' => 'Kazakhstan', 'KE' => 'Kenya', 'KI' => 'Kiribati', 'KP' => "Korea, Democratic People's Republic of", 'KR' => 'Korea, Republic of', 'KW' => 'Kuwait', 'KG' => 'Kyrgyzstan', 'LA' => "Lao People's Democratic Republic", 'LV' => 'Latvia', 'LB' => 'Lebanon', 'LS' => 'Lesotho', 'LR' => 'Liberia', 'LY' => 'Libyan Arab Jamahiriya', 'LI' => 'Liechtenstein', 'LT' => 'Lithuania', 'LU' => 'Luxembourg', 'MO' => 'Macao', 'MK' => 'Macedonia, the Former Yugoslav Republic of', 'MG' => 'Madagascar', 'MW' => 'Malawi', 'MY' => 'Malaysia', 'MV' => 'Maldives', 'ML' => 'Mali', 'MT' => 'Malta', 'MH' => 'Marshall Islands', 'MQ' => 'Martinique', 'MR' => 'Mauritania', 'MU' => 'Mauritius', 'YT' => 'Mayotte', 'MX' => 'Mexico', 'FM' => 'Micronesia, Federated States of', 'MD' => 'Moldova, Republic of', 'MC' => 'Monaco', 'MN' => 'Mongolia', 'MS' => 'Montserrat', 'MA' => 'Morocco', 'MZ' => 'Mozambique', 'MM' => 'Myanmar', 'NA' => 'Namibia', 'NR' => 'Nauru', 'NP' => 'Nepal', 'NL' => 'Netherlands', 'AN' => 'Netherlands Antilles', 'NC' => 'New Caledonia', 'NZ' => 'New Zealand', 'NI' => 'Nicaragua', 'NE' => 'Niger', 'NG' => 'Nigeria', 'NU' => 'Niue', 'NF' => 'Norfolk Island', 'MP' => 'Northern Mariana Islands', 'NO' => 'Norway', 'OM' => 'Oman', 'PK' => 'Pakistan', 'PW' => 'Palau', 'PS' => 'Palestinian Territory, Occupied', 'PA' => 'Panama', 'PG' => 'Papua New Guinea', 'PY' => 'Paraguay', 'PE' => 'Peru', 'PH' => 'Philippines', 'PN' => 'Pitcairn', 'PL' => 'Poland', 'PT' => 'Portugal', 'PR' => 'Puerto Rico', 'QA' => 'Qatar', 'RE' => 'Reunion', 'RO' => 'Romania', 'RU' => 'Russian Federation', 'RW' => 'Rwanda', 'SH' => 'Saint Helena', 'KN' => 'Saint Kitts and Nevis', 'LC' => 'Saint Lucia', 'PM' => 'Saint Pierre and Miquelon', 'VC' => 'Saint Vincent and the Grenadines', 'WS' => 'Samoa', 'SM' => 'San Marino', 'ST' => 'Sao Tome and Principe', 'SA' => 'Saudi Arabia', 'SN' => 'Senegal', 'ME' => 'Montenegro', 'RS' => 'Serbia', 'SC' => 'Seychelles', 'SL' => 'Sierra Leone', 'SG' => 'Singapore', 'SK' => 'Slovakia', 'SI' => 'Slovenia', 'SB' => 'Solomon Islands', 'SO' => 'Somalia', 'ZA' => 'South Africa', 'GS' => 'South Georgia and the South Sandwich Islands', 'ES' => 'Spain', 'LK' => 'Sri Lanka', 'SD' => 'Sudan', 'SR' => 'Suriname', 'SJ' => 'Svalbard and Jan Mayen', 'SZ' => 'Swaziland', 'SE' => 'Sweden', 'CH' => 'Switzerland', 'SY' => 'Syrian Arab Republic', 'TW' => 'Taiwan, Province of China', 'TJ' => 'Tajikistan', 'TZ' => 'Tanzania, United Republic of', 'TH' => 'Thailand', 'TL' => 'Timor-Leste', 'TG' => 'Togo', 'TK' => 'Tokelau', 'TO' => 'Tonga', 'TT' => 'Trinidad and Tobago', 'TN' => 'Tunisia', 'TR' => 'Turkey', 'TM' => 'Turkmenistan', 'TC' => 'Turks and Caicos Islands', 'TV' => 'Tuvalu', 'UG' => 'Uganda', 'UA' => 'Ukraine', 'AE' => 'United Arab Emirates', 'GB' => 'United Kingdom', 'US' => 'United States', 'UM' => 'United States Minor Outlying Islands', 'UY' => 'Uruguay', 'UZ' => 'Uzbekistan', 'VU' => 'Vanuatu', 'VE' => 'Venezuela', 'VN' => 'Viet Nam', 'VG' => 'Virgin Islands, British', 'VI' => 'Virgin Islands, U.s.', 'WF' => 'Wallis and Futuna', 'EH' => 'Western Sahara', 'YE' => 'Yemen', 'ZM' => 'Zambia', 'ZW' => 'Zimbabwe', ); } } // Premium extends this class and creates its own copy for its extra hooks, so both exist on purpose $wps_aa_options = new WPSunshine_Address_Autocomplete_Options();