From 1292549bfb37501e4f5545b0a11330d55d8199f9 Mon Sep 17 00:00:00 2001 From: Yanuar Date: Fri, 24 Jul 2026 10:36:13 +0700 Subject: [PATCH] fix(account): persist District address fields Add billing and shipping District fields to My Account address editing and converge account, classic checkout, and Blocks metadata. Keep billing and shipping values independent while clearing stale selections after postcode changes. --- Makefile | 3 +- assets/wp/js/account-address.js | 93 ++++++++++++++ inc/Base/Enqueue.php | 16 +++ inc/Controllers/AccountAddressController.php | 120 ++++++++++++++++++ inc/Controllers/CheckoutController.php | 58 +++++++-- inc/Init.php | 3 +- inc/Services/CustomerDistrictService.php | 86 +++++++++++++ lang/kiriminaja-official-id_ID.po | 4 + tests/MyAccountDistrictTest.php | 74 +++++++++++ ...hopVerseBlockCheckoutCompatibilityTest.php | 8 +- wc/KiriminajaShippingMethod.php | 1 + 11 files changed, 448 insertions(+), 18 deletions(-) create mode 100644 assets/wp/js/account-address.js create mode 100644 inc/Controllers/AccountAddressController.php create mode 100644 inc/Services/CustomerDistrictService.php create mode 100644 tests/MyAccountDistrictTest.php diff --git a/Makefile b/Makefile index 88df6504..04122876 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,8 @@ zip: rsync -a $(RSYNC_EXCLUDES) ./ $(STAGE_DIR)/ cp composer.json $(STAGE_DIR)/ @if [ -f composer.lock ]; then cp composer.lock $(STAGE_DIR)/; fi - cd $(STAGE_DIR) && composer install --no-dev --optimize-autoloader --no-interaction 2>/dev/null; rm -f $(STAGE_DIR)/composer.json $(STAGE_DIR)/composer.lock + (cd $(STAGE_DIR) && composer install --no-dev --optimize-autoloader --no-interaction 2>/dev/null) + rm -f $(STAGE_DIR)/composer.json $(STAGE_DIR)/composer.lock $(STAGE_DIR)/vendor/bin/.phpunit.result.cache @if [ "$(KIRIOF_ENV)" != "prd" ] && [ -f .env ]; then \ API_URL=$$(grep '^$(ENV_VAR_NAME)=' .env | head -1 | cut -d= -f2- | xargs); \ if [ -n "$$API_URL" ]; then \ diff --git a/assets/wp/js/account-address.js b/assets/wp/js/account-address.js new file mode 100644 index 00000000..e3435546 --- /dev/null +++ b/assets/wp/js/account-address.js @@ -0,0 +1,93 @@ +(function ($) { + "use strict"; + + function districtFields() { + return $( + "#billing_kiriof_destination_area, #shipping_kiriof_destination_area", + ); + } + + function districtNameField($field) { + var addressType = String($field.attr("id") || "").indexOf("shipping_") === 0 + ? "shipping" + : "billing"; + return $("#" + addressType + "_kiriof_destination_area_name"); + } + + function clearDistrict($field) { + $field.val("").trigger("change.select2"); + districtNameField($field).val(""); + } + + $(function () { + var select = $.fn.selectWoo || $.fn.select2; + var $fields = districtFields(); + + if (!$fields.length || !select || typeof kiriofAjax === "undefined") { + return; + } + + $fields.each(function () { + var $field = $(this); + select.call($field, { + minimumInputLength: 3, + placeholder: + typeof kiriofAccountAddress !== "undefined" + ? kiriofAccountAddress.selectOption + : "Select Option", + allowClear: true, + ajax: { + url: kiriofAjax.ajaxurl, + dataType: "json", + type: "POST", + delay: 250, + data: function (params) { + var term = params && params.term ? params.term : ""; + return { + action: "kiriminaja_subdistrict_search", + nonce: kiriofAjax.nonce, + term: term, + data: { term: term, search: term }, + }; + }, + processResults: function (response) { + var rows = response && response.success !== false && response.data + ? response.data + : []; + return { + results: $.map(rows, function (row) { + return { id: row.id, text: row.text }; + }), + }; + }, + cache: true, + }, + }); + + $field + .on("select2:select.kiriofAccountDistrict", function (event) { + var selected = event.params && event.params.data ? event.params.data : {}; + districtNameField($field).val(selected.text || ""); + }) + .on("select2:clear.kiriofAccountDistrict", function () { + districtNameField($field).val(""); + }); + }); + + $("#billing_postcode, #shipping_postcode").each(function () { + $(this).data("kiriofInitialPostcode", String($(this).val() || "")); + }).on( + "input.kiriofAccountDistrict change.kiriofAccountDistrict", + function () { + var currentPostcode = String($(this).val() || ""); + if (currentPostcode === String($(this).data("kiriofInitialPostcode") || "")) { + return; + } + var prefix = String(this.id || "").indexOf("shipping_") === 0 + ? "shipping" + : "billing"; + clearDistrict($("#" + prefix + "_kiriof_destination_area")); + }, + ); + }); +})(jQuery); diff --git a/inc/Base/Enqueue.php b/inc/Base/Enqueue.php index 36c992f0..20536b2e 100644 --- a/inc/Base/Enqueue.php +++ b/inc/Base/Enqueue.php @@ -60,6 +60,22 @@ function enqueueWp(){ KIRIOF_VERSION, array( 'in_footer' => true ) ); + if ( function_exists( 'is_account_page' ) && is_account_page() && function_exists( 'is_wc_endpoint_url' ) && is_wc_endpoint_url( 'edit-address' ) ) { + wp_enqueue_script( + 'kiriof-account-address', + KIRIOF_URL . 'assets/wp/js/account-address.js', + array( 'kiriof-script', 'jquery', 'select2' ), + KIRIOF_VERSION, + array( 'in_footer' => true ) + ); + wp_localize_script( + 'kiriof-account-address', + 'kiriofAccountAddress', + array( + 'selectOption' => __( 'Select Option', 'kiriminaja-official' ), + ) + ); + } // Localize script to pass ajax URL and nonce wp_localize_script( diff --git a/inc/Controllers/AccountAddressController.php b/inc/Controllers/AccountAddressController.php new file mode 100644 index 00000000..74a5d1f8 --- /dev/null +++ b/inc/Controllers/AccountAddressController.php @@ -0,0 +1,120 @@ +isEditAddressRequest( $address_type ) ) { + return $fields; + } + + $district = ( new CustomerDistrictService() )->get( get_current_user_id(), $address_type ); + $field_key = $address_type . '_kiriof_destination_area'; + $name_key = $address_type . '_kiriof_destination_area_name'; + $options = array( '' => __( 'Select Option', 'kiriminaja-official' ) ); + if ( '' !== $district['id'] && '' !== $district['name'] ) { + $options[ $district['id'] ] = $district['name']; + } + + $field = array( + 'label' => __( 'District', 'kiriminaja-official' ), + 'required' => true, + 'class' => array( 'form-row-wide' ), + 'type' => 'select', + 'options' => $options, + 'value' => $district['id'], + 'priority' => 61, + ); + $name_field = array( + 'type' => 'hidden', + 'value' => $district['name'], + 'priority' => 62, + ); + + $fields = $this->insertAfterPostcode( $fields, $field_key, $field ); + $fields = $this->insertAfterKey( $fields, $field_key, $name_key, $name_field ); + + return $fields; + } + + public function validateDistrict( int $user_id, string $address_type, array $address, $customer ): void { + unset( $user_id, $address, $customer ); + if ( ! in_array( $address_type, array( 'billing', 'shipping' ), true ) ) { + return; + } + + $district_id = $this->postedDistrictId( $address_type ); + $district_name = $this->postedDistrictName( $address_type ); + if ( $district_id < 1 || '' === $district_name ) { + wc_add_notice( __( 'Please select a District.', 'kiriminaja-official' ), 'error' ); + } + } + + public function saveDistrict( int $user_id, string $address_type ): void { + if ( ! in_array( $address_type, array( 'billing', 'shipping' ), true ) ) { + return; + } + + ( new CustomerDistrictService() )->save( + $user_id, + $address_type, + $this->postedDistrictId( $address_type ), + $this->postedDistrictName( $address_type ) + ); + } + + private function isEditAddressRequest( string $address_type = '' ): bool { + if ( ! function_exists( 'is_account_page' ) || ! is_account_page() || ! function_exists( 'is_wc_endpoint_url' ) || ! is_wc_endpoint_url( 'edit-address' ) ) { + return false; + } + if ( '' === $address_type ) { + return true; + } + + $requested_type = sanitize_key( (string) get_query_var( 'edit-address' ) ); + return '' === $requested_type || $requested_type === $address_type; + } + + private function postedDistrictId( string $address_type ): int { + $key = $address_type . '_kiriof_destination_area'; + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- WooCommerce verifies the account address nonce before this hook. + return isset( $_POST[ $key ] ) ? absint( wp_unslash( $_POST[ $key ] ) ) : 0; + } + + private function postedDistrictName( string $address_type ): string { + $key = $address_type . '_kiriof_destination_area_name'; + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- WooCommerce verifies the account address nonce before this hook. + return isset( $_POST[ $key ] ) ? sanitize_text_field( wp_unslash( $_POST[ $key ] ) ) : ''; + } + + private function insertAfterPostcode( array $fields, string $field_key, array $field ): array { + $postcode_key = 0 === strpos( $field_key, 'shipping_' ) ? 'shipping_postcode' : 'billing_postcode'; + return $this->insertAfterKey( $fields, $postcode_key, $field_key, $field ); + } + + private function insertAfterKey( array $fields, string $after_key, string $field_key, array $field ): array { + $result = array(); + foreach ( $fields as $key => $value ) { + $result[ $key ] = $value; + if ( $after_key === $key ) { + $result[ $field_key ] = $field; + } + } + if ( ! isset( $result[ $field_key ] ) ) { + $result[ $field_key ] = $field; + } + return $result; + } +} diff --git a/inc/Controllers/CheckoutController.php b/inc/Controllers/CheckoutController.php index 196eb708..6782fdd5 100644 --- a/inc/Controllers/CheckoutController.php +++ b/inc/Controllers/CheckoutController.php @@ -505,6 +505,10 @@ function kiriof_add_checkout_nonce_field(){ } function add_custom_select_options_field_and_script($checkout) { + if ( ! is_cart() && ! is_checkout() ) { + return; + } + if ( ! $this->kiriof_cart_needs_shipping() ) { $this->kiriof_clear_logistics_session(); $this->kiriof_render_virtual_cart_district_cleanup(); @@ -1151,6 +1155,26 @@ function afterCheckoutBeforeCreated($order,$data ){ //save meta subdistrict shipping woocommerce if( isset($_POST['kiriof_shipping_destination_area']) && !empty($_POST['kiriof_shipping_destination_area']) ) $order->update_meta_data( '_shipping_kiriof_destination_area', sanitize_text_field(wp_unslash($_POST['kiriof_shipping_destination_area'])) ); if( isset($_POST['kiriof_shipping_destination_area_name']) && !empty($_POST['kiriof_shipping_destination_area_name']) ) $order->update_meta_data( '_shipping_kiriof_destination_name', sanitize_text_field(wp_unslash($_POST['kiriof_shipping_destination_area_name'])) ); + + if ( is_user_logged_in() ) { + $district_service = new \KiriminAjaOfficial\Services\CustomerDistrictService(); + if ( isset( $_POST['kiriof_destination_area'] ) ) { + $district_service->save( + get_current_user_id(), + 'billing', + wp_unslash( $_POST['kiriof_destination_area'] ), + isset( $_POST['kiriof_destination_area_name'] ) ? wp_unslash( $_POST['kiriof_destination_area_name'] ) : '' + ); + } + if ( ! empty( $_POST['ship_to_different_address'] ) ) { + $district_service->save( + get_current_user_id(), + 'shipping', + isset( $_POST['kiriof_shipping_destination_area'] ) ? wp_unslash( $_POST['kiriof_shipping_destination_area'] ) : '', + isset( $_POST['kiriof_shipping_destination_area_name'] ) ? wp_unslash( $_POST['kiriof_shipping_destination_area_name'] ) : '' + ); + } + } //save meta Insurance shipping woocommerce if( isset($data['kiriof_shipping_insurance']) && !empty($data['kiriof_shipping_insurance']) ) $order->update_meta_data( '_shipping_kiriof_insurance', sanitize_text_field( ( wp_unslash($data['kiriof_shipping_insurance']) == true ) ? 'yes' : '' ) ); @@ -1578,17 +1602,21 @@ private function kiriof_remove_fields_checkout($fields,$fields_selected){ } private function kiriof_add_field_subdistrict( $fields ){ $field_key = $this->field_destination_key; + $district_service = new \KiriminAjaOfficial\Services\CustomerDistrictService(); + $customer = isset( WC()->customer ) && WC()->customer instanceof \WC_Customer ? WC()->customer : get_current_user_id(); + $saved_billing = $district_service->get( $customer, 'billing' ); + $saved_shipping = $district_service->get( $customer, 'shipping' ); //billing session - $destination_id = WC()->session->get('destination_id') ?? ''; - $destination_name = WC()->session->get('destination_name') ?? ''; + $destination_id = WC()->session->get('destination_id') ?: $saved_billing['id']; + $destination_name = WC()->session->get('destination_name') ?: $saved_billing['name']; $options = array( '' => esc_html__( 'Select Option', 'kiriminaja-official' ) ); if ( ! empty( $destination_id ) ) { $options[ $destination_id ] = $destination_name; } //shipping session - $shipping_dest_id = WC()->session->get('shipping_destination_id') ?? ''; - $shipping_dest_name = WC()->session->get('shipping_destination_name') ?? ''; + $shipping_dest_id = WC()->session->get('shipping_destination_id') ?: $saved_shipping['id']; + $shipping_dest_name = WC()->session->get('shipping_destination_name') ?: $saved_shipping['name']; $shipping_options = array( '' => esc_html__( 'Select Option', 'kiriminaja-official' ) ); if ( ! empty( $shipping_dest_id ) ) { $shipping_options[ $shipping_dest_id ] = $shipping_dest_name; @@ -2019,16 +2047,18 @@ public function kiriof_store_api_update_checkout( $data ) { // meta, NOT from WC()->session, so session-only storage leaves the // field empty in the cart response and can cause empty shipping rates. if ( isset( WC()->customer ) && is_object( WC()->customer ) ) { - if ( $destination_id > 0 ) { - WC()->customer->update_meta_data( 'shipping_kiriminaja-official/kiriof_destination_area', (string) $destination_id ); - WC()->customer->update_meta_data( 'billing_kiriminaja-official/kiriof_destination_area', (string) $destination_id ); - } else { - WC()->customer->update_meta_data( 'shipping_kiriminaja-official/kiriof_destination_area', '' ); - WC()->customer->update_meta_data( 'billing_kiriminaja-official/kiriof_destination_area', '' ); - } - WC()->customer->update_meta_data( 'shipping_kiriminaja-official/kiriof_destination_area_name', $destination_name ); - WC()->customer->update_meta_data( 'billing_kiriminaja-official/kiriof_destination_area_name', $destination_name ); - WC()->customer->save_meta_data(); + ( new \KiriminAjaOfficial\Services\CustomerDistrictService() )->save( + WC()->customer, + 'shipping', + $destination_id, + $destination_name + ); + ( new \KiriminAjaOfficial\Services\CustomerDistrictService() )->save( + WC()->customer, + 'billing', + $destination_id, + $destination_name + ); } WC()->session->set( 'kiriof_insurance', $insurance ); diff --git a/inc/Init.php b/inc/Init.php index 3b3d2a53..562599cc 100644 --- a/inc/Init.php +++ b/inc/Init.php @@ -25,6 +25,7 @@ public static function get_services(){ Controllers\TransactionProcessController::class, Controllers\ShippingDiscountCouponController::class, Controllers\CheckoutController::class, + Controllers\AccountAddressController::class, Controllers\TrackingFrontPageController::class, Controllers\EditOrderController::class, Controllers\CodAdjustmentController::class, @@ -51,4 +52,4 @@ public static function register_services(){ private static function instantiate($class ){ return new $class(); } -} \ No newline at end of file +} diff --git a/inc/Services/CustomerDistrictService.php b/inc/Services/CustomerDistrictService.php new file mode 100644 index 00000000..7e2ba503 --- /dev/null +++ b/inc/Services/CustomerDistrictService.php @@ -0,0 +1,86 @@ +normalizeAddressType( $address_type ); + $id = $this->readMeta( $customer, $address_type . '_' . self::FIELD_ID ); + $name = $this->readMeta( $customer, $address_type . '_' . self::FIELD_NAME ); + + if ( '' === $id ) { + $id = $this->readMeta( $customer, $address_type . '_kiriminaja-official/' . self::FIELD_ID ); + } + if ( '' === $name ) { + $name = $this->readMeta( $customer, $address_type . '_kiriminaja-official/' . self::FIELD_NAME ); + } + + return array( + 'id' => sanitize_text_field( $id ), + 'name' => sanitize_text_field( $name ), + ); + } + + /** + * Persist canonical and Blocks-compatible District metadata. + * + * @param \WC_Customer|int $customer Customer object or user ID. + * @param string $address_type Billing or shipping. + * @param string|int $district_id KiriminAja District ID. + * @param string $district_name District display label. + */ + public function save( $customer, string $address_type, $district_id, string $district_name ): void { + $address_type = $this->normalizeAddressType( $address_type ); + $district_id = absint( $district_id ); + $district_name = sanitize_text_field( $district_name ); + $values = array( + $address_type . '_' . self::FIELD_ID => $district_id > 0 ? (string) $district_id : '', + $address_type . '_' . self::FIELD_NAME => $district_name, + $address_type . '_kiriminaja-official/' . self::FIELD_ID => $district_id > 0 ? (string) $district_id : '', + $address_type . '_kiriminaja-official/' . self::FIELD_NAME => $district_name, + ); + + if ( $customer instanceof \WC_Customer ) { + foreach ( $values as $key => $value ) { + $customer->update_meta_data( $key, $value ); + } + $customer->save_meta_data(); + return; + } + + $user_id = absint( $customer ); + if ( $user_id < 1 ) { + return; + } + foreach ( $values as $key => $value ) { + update_user_meta( $user_id, $key, $value ); + } + } + + private function readMeta( $customer, string $key ): string { + if ( $customer instanceof \WC_Customer ) { + return (string) $customer->get_meta( $key, true ); + } + + $user_id = absint( $customer ); + return $user_id > 0 ? (string) get_user_meta( $user_id, $key, true ) : ''; + } + + private function normalizeAddressType( string $address_type ): string { + return 'shipping' === $address_type ? 'shipping' : 'billing'; + } +} diff --git a/lang/kiriminaja-official-id_ID.po b/lang/kiriminaja-official-id_ID.po index 08416628..d7a3cc05 100644 --- a/lang/kiriminaja-official-id_ID.po +++ b/lang/kiriminaja-official-id_ID.po @@ -1236,6 +1236,10 @@ msgstr "Pilih Kecamatan" msgid "Select Option" msgstr "Pilih Opsi" +#: inc/Controllers/AccountAddressController.php +msgid "Please select a District." +msgstr "Silakan pilih Kecamatan." + #: templates/woocommerce/cart/shipping-calculator.php:30 msgid "Select a country / region…" msgstr "Pilih negara / wilayah…" diff --git a/tests/MyAccountDistrictTest.php b/tests/MyAccountDistrictTest.php new file mode 100644 index 00000000..b852d5e3 --- /dev/null +++ b/tests/MyAccountDistrictTest.php @@ -0,0 +1,74 @@ +assertStringContainsString("woocommerce_address_to_edit", $content); + $this->assertStringContainsString("woocommerce_after_save_address_validation", $content); + $this->assertStringContainsString("woocommerce_customer_save_address", $content); + $this->assertStringContainsString("is_wc_endpoint_url( 'edit-address' )", $content); + $this->assertStringContainsString("\$address_type . '_kiriof_destination_area'", $content); + } + + #[Test] + public function account_district_service_reads_and_writes_canonical_and_legacy_metadata(): void + { + $content = file_get_contents(PLUGIN_DIR . '/inc/Services/CustomerDistrictService.php'); + + $this->assertStringContainsString("\$address_type . '_' . self::FIELD_ID", $content); + $this->assertStringContainsString("\$address_type . '_kiriminaja-official/' . self::FIELD_ID", $content); + $this->assertStringContainsString("update_user_meta", $content); + $this->assertStringContainsString("update_meta_data", $content); + } + + #[Test] + public function account_district_script_supports_search_selection_and_postcode_invalidation(): void + { + $content = file_get_contents(PLUGIN_DIR . '/assets/wp/js/account-address.js'); + + $this->assertStringContainsString('kiriminaja_subdistrict_search', $content); + $this->assertStringContainsString('kiriofAjax.nonce', $content); + $this->assertStringContainsString('select2:select.kiriofAccountDistrict', $content); + $this->assertStringContainsString('select2:clear.kiriofAccountDistrict', $content); + $this->assertStringContainsString('#billing_postcode, #shipping_postcode', $content); + $this->assertStringContainsString('clearDistrict', $content); + } + + #[Test] + public function checkout_footer_district_renderer_is_not_global(): void + { + $content = file_get_contents(PLUGIN_DIR . '/inc/Controllers/CheckoutController.php'); + $start = strpos($content, 'function add_custom_select_options_field_and_script'); + $end = strpos($content, 'private function kiriof_render_virtual_cart_district_cleanup', $start); + $method = substr($content, $start, $end - $start); + + $this->assertStringContainsString('if ( ! is_cart() && ! is_checkout() )', $method); + } + + #[Test] + public function checkout_uses_customer_district_as_fallback_and_persists_canonical_meta(): void + { + $content = file_get_contents(PLUGIN_DIR . '/inc/Controllers/CheckoutController.php'); + + $this->assertStringContainsString("CustomerDistrictService()", $content); + $this->assertStringContainsString("\$district_service->get( \$customer, 'billing' )", $content); + $this->assertStringContainsString("\$district_service->get( \$customer, 'shipping' )", $content); + $this->assertStringContainsString("\$district_service->save(", $content); + } + + #[Test] + public function shipping_method_prefers_canonical_shipping_district_metadata(): void + { + $content = file_get_contents(PLUGIN_DIR . '/wc/KiriminajaShippingMethod.php'); + + $this->assertStringContainsString("'shipping_kiriof_destination_area'", $content); + $this->assertStringContainsString("'shipping_kiriminaja-official/kiriof_destination_area'", $content); + } +} diff --git a/tests/ShopVerseBlockCheckoutCompatibilityTest.php b/tests/ShopVerseBlockCheckoutCompatibilityTest.php index 1cf5c296..37bcc94a 100644 --- a/tests/ShopVerseBlockCheckoutCompatibilityTest.php +++ b/tests/ShopVerseBlockCheckoutCompatibilityTest.php @@ -1901,7 +1901,9 @@ public function store_api_update_callback_does_not_overwrite_visible_block_postc $content = file_get_contents(PLUGIN_DIR . '/inc/Controllers/CheckoutController.php'); $start = strpos($content, 'public function kiriof_store_api_update_checkout'); $this->assertNotFalse($start, 'Store API update callback must exist'); - $methodBody = substr($content, $start, 6000); + $end = strpos($content, 'public function kiriof_ajax_session_save', $start); + $this->assertNotFalse($end, 'Store API update callback boundary must exist'); + $methodBody = substr($content, $start, $end - $start); $this->assertStringContainsString( "WC()->session->set( 'kiriof_checkout_postcode', \$postcode );", @@ -1928,7 +1930,9 @@ public function store_api_update_callback_recalculates_totals_after_block_destin $content = file_get_contents(PLUGIN_DIR . '/inc/Controllers/CheckoutController.php'); $start = strpos($content, 'public function kiriof_store_api_update_checkout'); $this->assertNotFalse($start, 'Store API update callback must exist'); - $methodBody = substr($content, $start, 6000); + $end = strpos($content, 'public function kiriof_ajax_session_save', $start); + $this->assertNotFalse($end, 'Store API update callback boundary must exist'); + $methodBody = substr($content, $start, $end - $start); $destinationPosition = strpos($methodBody, "WC()->session->set( 'kiriof_destination_area', \$destination_id );"); $calculatePosition = strpos($methodBody, 'WC()->cart->calculate_totals();'); diff --git a/wc/KiriminajaShippingMethod.php b/wc/KiriminajaShippingMethod.php index d8070d77..4be1c0ba 100644 --- a/wc/KiriminajaShippingMethod.php +++ b/wc/KiriminajaShippingMethod.php @@ -114,6 +114,7 @@ public function calculate_shipping( $package = array() ){ try { if ( isset( WC()->customer ) && is_object( WC()->customer ) ) { $meta_keys = array( + 'shipping_kiriof_destination_area', 'shipping_kiriminaja-official/kiriof_destination_area', 'kiriminaja-official/kiriof_destination_area', '_wc_blocks_checkout_field_kiriminaja-official/kiriof_destination_area',