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 );
?>
'',
'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 ) {
?>
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() {
?>
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 );
?>