diff --git a/includes/class-tmdo-schema-registry.php b/includes/class-tmdo-schema-registry.php index 442af5d..95225ff 100644 --- a/includes/class-tmdo-schema-registry.php +++ b/includes/class-tmdo-schema-registry.php @@ -282,7 +282,8 @@ class TMDO_Schema_Registry { * Whether a field may appear in the public listings endpoints: declared * show_in_rest, not a protected meta key (leading underscore — WordPress * hides those from public output, e.g. _purchase_note), and not named like a - * credential (tokens, secrets, passwords, API keys), whatever it declares. + * credential (tokens, secrets, passwords, API keys) or a contact / location + * detail (email, phone, address, IP), whatever it declares. * * @param array $field Registered field. * @return bool @@ -291,7 +292,9 @@ class TMDO_Schema_Registry { $key = (string) ( $field['meta_key'] ?? '' ); return ! empty( $field['show_in_rest'] ) && 0 !== strpos( $key, '_' ) - && 1 !== preg_match( '/token|secret|passw|api_?key|private_?key|credential|salt|nonce/i', $key . ' ' . ( $field['column'] ?? '' ) ); + && 1 !== preg_match( '/token|secret|passw|api_?key|private_?key|credential|salt|nonce/i', $key . ' ' . ( $field['column'] ?? '' ) ) + // Contact and location details (2.3 PR-096): private even when declared public. + && 1 !== preg_match( '/e_?mail|phone|address|(^|_)ip(_|$|\s)/i', $key . ' ' . ( $field['column'] ?? '' ) ); } /** diff --git a/tests/unit/RestApiTest.php b/tests/unit/RestApiTest.php index b30cf7c..60c9aba 100644 --- a/tests/unit/RestApiTest.php +++ b/tests/unit/RestApiTest.php @@ -164,6 +164,21 @@ class RestApiTest extends TestCase { $this->assertSame( array( 'id', 'post_type', 'hp_price' ), array_keys( $data ) ); } + public function test_contact_and_address_keys_stay_private_even_when_declared_public(): void { + $private = array( 'hp_email', 'hp_contact_e_mail', 'hp_phone_number', 'hp_address', 'billing_address_1', 'hp_ip', 'hp_client_ip_addr' ); + $public = array( 'hp_price', 'hp_description', 'hp_tip_amount', 'hp_shipping_days' ); + $fields = array(); + $values = array(); + foreach ( array_merge( $private, $public ) as $key ) { + $fields[] = array( 'meta_key' => $key, 'zone' => 'cold', 'show_in_rest' => true ); + $values[ $key ] = 'v'; + } + + $data = $this->listing_with( $fields, $values ); + + $this->assertSame( array_merge( array( 'id', 'post_type' ), $public ), array_keys( $data ) ); + } + public function test_rest_visible_columns_exclude_protected_and_credential_keys(): void { $registry = WPDO_Schema_Registry::instance(); $registry->register( 'test', array( 'post_type' => 'hp_listing', 'meta_key' => 'hp_price', 'zone' => 'hot', 'column' => 'hp_price', 'show_in_rest' => true ) );