id = "addresszen"; $this->method_title = __( "AddressZen - Address Lookup", "addresszen" ); $this->method_description = __( "US and International Address Verification at checkout", "addresszen" ); // Load the settings $this->init_form_fields(); $this->init_settings(); $this->config = (object) [ "addresszen_enabled" => $this->get_option("addresszen_enabled"), "addresszen_api_key" => $this->get_option("addresszen_api_key"), "addresszen_populate_organisation" => $this->get_option( "addresszen_populate_organisation" ), "addresszen_populate_county" => $this->get_option( "addresszen_populate_county" ), "addresszen_watch_country" => $this->get_option( "addresszen_watch_country" ), "addresszen_separate_finder" => $this->get_option( "addresszen_separate_finder" ), "addresszen_autocomplete_override" => $this->get_option( "addresszen_autocomplete_override" ), "addresszen_address_finder_label" => $this->get_option( "addresszen_address_finder_label" ), "addresszen_address_line_3_field" => $this->get_option( "addresszen_address_line_3_field" ), ]; add_action("woocommerce_update_options_integration_" . $this->id, [ $this, "process_admin_options", ]); // Add action for admin settings page if (is_admin()) { add_action("admin_footer", [$this, "add_admin_settings_js"]); } if ($this->config->addresszen_enabled === "yes") { //AddressZen custom action - only load legacy script on non-blocks checkout add_action("wp_enqueue_scripts", [$this, "load_scripts"]); add_action("admin_enqueue_scripts", [$this, "load_admin_scripts"]); } } public function init_form_fields() { // Tab 1: Basic Settings $this->basic_fields = [ "addresszen_required" => [ "title" => __("Required", "addresszen"), "type" => "title", "description" => "", "id" => "addresszen_required", ], "addresszen_enabled" => [ "id" => "addresszen_enabled", "title" => __("Enabled", "addresszen"), "type" => "checkbox", "description" => __( "Globally activate or deactivate this plugin", "addresszen" ), "default" => "yes", ], "addresszen_api_key" => [ "id" => "addresszen_api_key", "title" => __("API Key", "addresszen"), "type" => "text", "description" => __( "Security Note: Before going into production, restrict your API key to requests from your domain URL only.", "addresszen" ), ], "addresszen_features" => [ "title" => __("Features", "addresszen"), "type" => "title", "description" => "", "id" => "addresszen_features", ], "addresszen_autocomplete" => [ "id" => "addresszen_autocomplete", "title" => __("Enable Address Lookup", "addresszen"), "type" => "checkbox", "description" => __( "Toggles customer facing Address Lookup functionality in checkout and accounts pages", "addresszen" ), "default" => "yes", ], "addresszen_admin_autocomplete" => [ "id" => "addresszen_admin_autocomplete", "title" => __("Enable Admin Address Lookup", "addresszen"), "type" => "checkbox", "description" => __( "Toggles Address Lookup functionality on your WooCommerce administrative pages like order creation and editing", "addresszen" ), "default" => "yes", ], ]; // Tab 2: Advanced Settings $this->advanced_fields = [ "addresszen_behaviour" => [ "title" => __("Behaviour", "addresszen"), "type" => "title", "description" => "", "id" => "addresszen_behaviour", ], "addresszen_watch_country" => [ "id" => "addresszen_watch_country", "title" => __( "Enable Address Validation based on country", "addresszen" ), "type" => "checkbox", "description" => __( "Enabling this feature will disable Address Lookup when an unsupported territory is selected", "addresszen" ), "default" => "false", ], "addresszen_separate_finder" => [ "id" => "addresszen_separate_finder", "title" => __( "Create a Separate Field for Address Lookup", "addresszen" ), "type" => "checkbox", "description" => __( "Enabling this feature will move the Address Lookup into a separate input field above the main address form", "addresszen" ), "default" => "false", ], "addresszen_separate_finder_position" => [ "id" => "addresszen_separate_finder_position", "title" => __( "Separate Lookup Position", "addresszen" ), "type" => "select", "description" => __( "Choose where to position the separate Address Lookup field", "addresszen" ), "default" => "above_address", "options" => [ "above_address" => __("Above Address Line 1", "addresszen"), "above_company" => __("Above Company Field", "addresszen"), ], ], "addresszen_address_finder_label" => [ "id" => "addresszen_address_finder_label", "title" => __("Address Finder Label", "addresszen"), "type" => "text", "description" => __( "Customise the label shown on the separate Address Finder input field. Leave blank for the default.", "addresszen" ), "default" => "", ], "addresszen_hide_address_fields" => [ "id" => "addresszen_hide_address_fields", "title" => __( "Hide Address Fields Until Selection", "addresszen" ), "type" => "checkbox", "description" => __( "When using the separate Address Lookup, this will hide the address fields until an address is selected.", "addresszen" ), "default" => "false", ], "addresszen_allow_manual_entry" => [ "id" => "addresszen_allow_manual_entry", "title" => __( "Allow Manual Address Entry", "addresszen" ), "type" => "checkbox", "description" => __( "Show a link to allow customers to enter their address manually instead of using Address Lookup", "addresszen" ), "default" => "yes", ], "addresszen_address_output" => [ "title" => __("Address Output", "addresszen"), "type" => "title", "description" => "", "id" => "addresszen_address_output", ], "addresszen_populate_organisation" => [ "id" => "addresszen_populate_organisation", "title" => __("Remove Organisation Name", "addresszen"), "type" => "checkbox", "description" => __( "Removes the Company name from the address lines to avoid duplicate with Company Name field", "addresszen" ), "default" => "yes", ], "addresszen_populate_county" => [ "id" => "addresszen_populate_county", "title" => __("Enable County/State", "addresszen"), "type" => "checkbox", "description" => __( "This will populate the county/state field from the address data.", "addresszen" ), "default" => "yes", ], "addresszen_address_line_3_field" => [ "id" => "addresszen_address_line_3_field", "title" => __("Third Address Line Field", "addresszen"), "type" => "text", "description" => __( "Block checkout only. ID of an additional address field registered with woocommerce_register_additional_checkout_field (e.g. my-plugin/address-3) to receive the third address line. Leave blank to append the third line to Address line 2.", "addresszen" ), "default" => "", ], "addresszen_overrides" => [ "title" => __("Configuration Overrides", "addresszen"), "type" => "title", "description" => __("These settings allow for highly customisable integrations. Invalid input will break your integration.", "addresszen"), "id" => "addresszen_overrides", ], "addresszen_autocomplete_override" => [ "id" => "addresszen_autocomplete_override", "title" => __( "Address Lookup Configuration Override", "addresszen" ), "type" => "textarea", "description" => __( "JSON configuration to override Address Lookup settings. Leave blank to disable.", "addresszen" ), "default" => "", ], ]; // Tab 3: Validation Settings $this->validation_fields = [ "addresszen_validation" => [ "title" => __("Address Format", "addresszen"), "type" => "title", "description" => __("Configure address format validation and transformations", "addresszen"), "id" => "addresszen_validation", ], "addresszen_limit_line_one" => [ "id" => "addresszen_limit_line_one", "title" => __("Limit Address Line One Length", "addresszen"), "type" => "checkbox", "description" => __( "Enable to enforce a maximum character limit on address line one", "addresszen" ), "default" => "no", ], "addresszen_max_line_one" => [ "id" => "addresszen_max_line_one", "title" => __("Maximum Address Line One Length", "addresszen"), "type" => "number", "description" => __( "Maximum number of characters allowed in address line one (default: 40)", "addresszen" ), "default" => "40", "custom_attributes" => [ "min" => "10", "max" => "255", ], ], "addresszen_transliterate" => [ "id" => "addresszen_transliterate", "title" => __("Transliterate Accented Characters", "addresszen"), "type" => "checkbox", "description" => __( "Convert accented and special characters to their ASCII equivalents (e.g., é → e, ñ → n)", "addresszen" ), "default" => "no", ], "addresszen_ascii_only" => [ "id" => "addresszen_ascii_only", "title" => __("ASCII Characters Only", "addresszen"), "type" => "checkbox", "description" => __( "Only allow ASCII characters and common accented characters. Special characters will be removed.", "addresszen" ), "default" => "no", ], "addresszen_us_zip5_only" => [ "id" => "addresszen_us_zip5_only", "title" => __("Use Standard US ZIP Codes", "addresszen"), "type" => "checkbox", "description" => __( "Use US ZIP codes in the traditional 5-digit format (90210) instead of the ZIP+4 format (90210-1234)", "addresszen" ), "default" => "yes", ], "addresszen_company" => [ "title" => __("Company Name Handling", "addresszen"), "type" => "title", "description" => __("Configure how company names are handled in addresses", "addresszen"), "id" => "addresszen_company", ], "addresszen_fill_company" => [ "id" => "addresszen_fill_company", "title" => __("Populate Company Name Field", "addresszen"), "type" => "checkbox", "description" => __( "Automatically populate the company name field from the address if present", "addresszen" ), "default" => "no", ], "addresszen_restrictions" => [ "title" => __("Address Restrictions", "addresszen"), "type" => "title", "description" => __("Block certain types of addresses", "addresszen"), "id" => "addresszen_restrictions", ], "addresszen_block_po_boxes" => [ "id" => "addresszen_block_po_boxes", "title" => __("Block PO Box Addresses", "addresszen"), "type" => "checkbox", "description" => __( "Prevent customers from using PO Box addresses", "addresszen" ), "default" => "no", ], ]; // Merge all fields for saving/processing (required by WC_Settings_API) $this->form_fields = array_merge($this->basic_fields, $this->advanced_fields, $this->validation_fields); } /** * Override admin_options to render tabbed interface */ public function admin_options() { ?>

get_method_title()); ?>

get_method_description())); ?> display_errors(); ?>
generate_settings_html($this->basic_fields, false); ?>
$this->to_bool( $this->get_option("addresszen_enabled") ), "publicKey" => $this->get_option("addresszen_api_key"), "autocomplete" => $this->to_bool( $this->get_option("addresszen_autocomplete") ), "watchCountry" => $this->to_bool( $this->get_option("addresszen_watch_country") ), "separateFinder" => $this->to_bool( $this->get_option("addresszen_separate_finder") ), "separateFinderPosition" => $this->get_option( "addresszen_separate_finder_position", "above_address" ), "hideAddressFields" => $this->to_bool( $this->get_option("addresszen_hide_address_fields") ), "allowManualEntry" => $this->to_bool( $this->get_option("addresszen_allow_manual_entry") ), "removeOrganisation" => $this->to_bool( $this->get_option("addresszen_populate_organisation") ), "populateCounty" => $this->to_bool( $this->get_option("addresszen_populate_county") ), "autocompleteOverride" => $this->get_option( "addresszen_autocomplete_override" ), "addressFinderLabel" => $this->get_option( "addresszen_address_finder_label" ), "addressLine3Field" => trim( (string) $this->get_option("addresszen_address_line_3_field") ), // Validation settings "limitLineOne" => $this->to_bool( $this->get_option("addresszen_limit_line_one") ), "maxLineOne" => (int) $this->get_option("addresszen_max_line_one", 40), "transliterate" => $this->to_bool( $this->get_option("addresszen_transliterate") ), "asciiOnly" => $this->to_bool( $this->get_option("addresszen_ascii_only") ), "fillCompany" => $this->to_bool( $this->get_option("addresszen_fill_company") ), "blockPoBoxes" => $this->to_bool( $this->get_option("addresszen_block_po_boxes") ), "usZip5Only" => $this->to_bool( $this->get_option("addresszen_us_zip5_only", "yes") ), ]; } private function get_config() { $options = $this->get_options(); // Legacy format for window.idpcConfig (keeps apiKey naming) $options["apiKey"] = $options["publicKey"]; return $options; } private function get_config_json() { $config = $this->get_config(); // Validate and sanitize JSON overrides $autocomplete_override = "{}"; if (strlen($config["autocompleteOverride"]) > 0) { $sanitized = wp_kses($config["autocompleteOverride"], []); $decoded = html_entity_decode($sanitized); json_decode($decoded); if (json_last_error() === JSON_ERROR_NONE) { $autocomplete_override = $decoded; } else { if (defined('WP_DEBUG') && WP_DEBUG) { error_log("[AddressZen] Invalid JSON in autocompleteOverride setting"); } } } $config["autocompleteOverride"] = "%autocompleteOverride%"; $json = json_encode($config, JSON_FORCE_OBJECT); $json = str_replace( "\"%autocompleteOverride%\"", $autocomplete_override, $json ); if ($json === false) { if (defined('WP_DEBUG') && WP_DEBUG) { error_log("[AddressZen] Failed to encode config"); } return "{}"; } return $json; } public function load_scripts() { // Skip legacy script on blocks checkout - handled by blocks integration if ($this->is_block_checkout()) { return; } $this->add_autocomplete_styles(); $this->add_idpc_bindings(); } /** * Check if the current checkout is using WooCommerce Blocks * * @return bool */ private function is_block_checkout() { if (function_exists('has_block')) { $checkout_page_id = function_exists('wc_get_page_id') ? wc_get_page_id('checkout') : 0; if ($checkout_page_id) { $post = get_post($checkout_page_id); if ($post && has_block('woocommerce/checkout', $post)) { return true; } } } return false; } public function load_admin_scripts() { $enabled = $this->to_bool( $this->get_option("addresszen_admin_autocomplete") ); if(!$enabled) return; $this->add_autocomplete_styles(); $this->add_admin_idpc_bindings(); } /** * Add autocomplete css */ private function add_autocomplete_styles() { wp_enqueue_style( "addresszen-autocomplete-style", ADDRESSZEN_URL . "css/addresszen.css", [], ADDRESSZEN_VERSION ); } /** * Add config and bind plugin to page */ private function add_idpc_bindings() { //need unescape the json $script = "window.idpcConfig = " . $this->get_config_json() . ";"; wp_enqueue_script( "addresszen-bindings", ADDRESSZEN_URL . "js/woocommerce.min.js", [], ADDRESSZEN_VERSION, true ); wp_add_inline_script("addresszen-bindings", $script, "before"); } /** * Init js plugin on the checkout page */ private function add_admin_idpc_bindings() { //need unescaped json $script = "window.idpcConfig = " . $this->get_config_json() . ";"; wp_enqueue_script( "addresszen-bindings", ADDRESSZEN_URL . "js/admin-woocommerce.min.js", [], ADDRESSZEN_VERSION, true ); wp_add_inline_script("addresszen-bindings", $script, "before"); } /** * Add JavaScript for admin settings page to conditionally show/hide options */ public function add_admin_settings_js() { // Only add the script on the AddressZen settings page if (!isset($_GET['page']) || sanitize_text_field(wp_unslash($_GET['page'])) !== 'wc-settings' || !isset($_GET['tab']) || sanitize_text_field(wp_unslash($_GET['tab'])) !== 'integration' || !isset($_GET['section']) || sanitize_text_field(wp_unslash($_GET['section'])) !== 'addresszen') { return; } // Enqueue the admin settings script wp_enqueue_script( 'addresszen-admin-settings', ADDRESSZEN_URL . 'js/admin-settings.js', array('jquery'), ADDRESSZEN_VERSION, true ); } } endif;