From d3ddbb893345643854b8c86fd0cf729e20b233b5 Mon Sep 17 00:00:00 2001 From: wpdev Date: Fri, 25 Sep 2026 22:35:30 +0800 Subject: [PATCH] fix(2meet-data-optimizer-hivepress-addon): register enabled social links as hp_{name} - hivepress-social-links stores each link as hp_{name} (hp_facebook, not hp_facebook_url) and lets admins enable links separately for listings and vendors; the hardcoded 7 *_url vendor keys never matched real meta - Read hp_listing_social_links / hp_vendor_social_links and register each enabled link on its own post type, so custom links (e.g. line_oa) work - dev34 check: meta holds hp_instagram / hp_website, and zero *_url keys Verify: vendor/bin/phpunit --filter HivePressSocialLinksAdapterTest; addon unit 156 OK, integration 57 OK PR: PR-010 --- ...ss-tmdo-hivepress-social-links-adapter.php | 69 ++++++++++--------- tests/unit/SocialLinksAdapterTest.php | 38 +++++++--- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/includes/hivepress/adapters/class-tmdo-hivepress-social-links-adapter.php b/includes/hivepress/adapters/class-tmdo-hivepress-social-links-adapter.php index 7636de1..225bef5 100644 --- a/includes/hivepress/adapters/class-tmdo-hivepress-social-links-adapter.php +++ b/includes/hivepress/adapters/class-tmdo-hivepress-social-links-adapter.php @@ -2,13 +2,13 @@ /** * Social Links adapter — `hivepress-social-links`. * - * Adds social URL fields to vendor profiles (Facebook, Instagram, Twitter, - * LinkedIn, YouTube, etc.). Stored in postmeta as `hp_social_*` keys. + * The addon adds one attribute per social link the admin enables, separately + * for listings (`hp_listing_social_links`) and vendors (`hp_vendor_social_links`). + * Each attribute is stored in postmeta as `hp_{name}` (e.g. `hp_facebook`). * * Display-only — never used in search/filter — so the right zone is Cold - * (object cache + JSON blob fallback). Listing page reads ~7 social URLs; - * caching them as a single blob keyed on vendor_id eliminates 7 postmeta - * lookups per render. + * (object cache + JSON blob fallback): one blob per post replaces one + * postmeta lookup per link on every render. * * @package WP_Data_Optimizer * @since 3.0.0 @@ -27,25 +27,6 @@ if ( ! class_exists( 'TMDO_HivePress_Social_Links_Adapter' ) ) { use TMDO_HivePress_Adapter_Trait; - /** - * Social URL meta keys owned by this addon. - * - * Sources (HivePress 1.0.3 default field set): - * facebook_url, instagram_url, twitter_url, linkedin_url, - * youtube_url, telegram_url, whatsapp_url - * - * @var array - */ - private const SOCIAL_KEYS = array( - 'hp_facebook_url', - 'hp_instagram_url', - 'hp_twitter_url', - 'hp_linkedin_url', - 'hp_youtube_url', - 'hp_telegram_url', - 'hp_whatsapp_url', - ); - /** * Constructor — bind register hooks via inherited trait. */ @@ -74,24 +55,44 @@ if ( ! class_exists( 'TMDO_HivePress_Social_Links_Adapter' ) ) { } /** - * Register vendor social URL fields to Cold zone. + * Register the enabled social link fields to the Cold zone. * * @param TMDO_Schema_Registry $registry Schema registry singleton. */ public function on_register_fields( TMDO_Schema_Registry $registry ): void { $fields = array(); - foreach ( self::SOCIAL_KEYS as $key ) { - $fields[] = array( - 'post_type' => 'hp_vendor', - 'meta_key' => $key, - 'zone' => 'cold', - 'cache_group' => 'wpdo_cold_hp_vendor', - 'cache_ttl' => HOUR_IN_SECONDS, - ); + foreach ( $this->enabled_meta_keys() as $post_type => $keys ) { + foreach ( $keys as $key ) { + $fields[] = array( + 'post_type' => $post_type, + 'meta_key' => $key, + 'zone' => 'cold', + 'cache_group' => 'wpdo_cold_' . $post_type, + 'cache_ttl' => HOUR_IN_SECONDS, + ); + } } $registry->register_many( $this->plugin_slug(), $fields ); } + /** + * Meta keys of the social links enabled in the addon settings. + * + * @return array> post_type => meta keys. + */ + private function enabled_meta_keys(): array { + $keys = array(); + foreach ( array( 'listing', 'vendor' ) as $model ) { + foreach ( (array) get_option( 'hp_' . $model . '_social_links', array() ) as $name ) { + $name = sanitize_key( (string) $name ); + if ( '' !== $name ) { + $keys[ 'hp_' . $model ][] = 'hp_' . $name; + } + } + } + return $keys; + } + /** * Doctor probe — cold zone uses cache; verify cache layer is reachable. * @@ -100,7 +101,7 @@ if ( ! class_exists( 'TMDO_HivePress_Social_Links_Adapter' ) ) { public function doctor_check(): array { return array( 'ok' => true, - 'message' => sprintf( 'hivepress-social-links: %d cold fields registered', count( self::SOCIAL_KEYS ) ), + 'message' => sprintf( 'hivepress-social-links: %d cold fields registered', array_sum( array_map( 'count', $this->enabled_meta_keys() ) ) ), ); } diff --git a/tests/unit/SocialLinksAdapterTest.php b/tests/unit/SocialLinksAdapterTest.php index b14b543..eb0ce82 100644 --- a/tests/unit/SocialLinksAdapterTest.php +++ b/tests/unit/SocialLinksAdapterTest.php @@ -18,6 +18,8 @@ class HivePressSocialLinksAdapterTest extends TestCase { $prop->setAccessible( true ); $prop->setValue( null, null ); + unset( $GLOBALS['_wp_options']['hp_vendor_social_links'], $GLOBALS['_wp_options']['hp_listing_social_links'] ); + $this->adapter = new WPDO_HivePress_Social_Links_Adapter(); } @@ -30,25 +32,39 @@ class HivePressSocialLinksAdapterTest extends TestCase { $this->assertSame( 'HivePress\\SocialLinks\\Plugin', $this->adapter->detection_class() ); } - public function test_on_register_fields_registers_seven_cold_fields(): void { + public function test_registers_enabled_links_per_model(): void { + // hivepress-social-links stores each enabled link as the attribute hp_{name}, + // with separate admin selections for listings and vendors. + update_option( 'hp_vendor_social_links', array( 'facebook', 'website' ) ); + update_option( 'hp_listing_social_links', array( 'instagram' ) ); + $registry = WPDO_Schema_Registry::instance(); $this->adapter->on_register_fields( $registry ); - // All seven social URL fields should land in cold zone on hp_vendor. - $facebook = $registry->get_field( 'hp_vendor', 'hp_facebook_url' ); - $this->assertSame( 'cold', $facebook['zone'] ); + $this->assertSame( 'cold', $registry->get_field( 'hp_vendor', 'hp_facebook' )['zone'] ); + $this->assertSame( 'cold', $registry->get_field( 'hp_vendor', 'hp_website' )['zone'] ); + $this->assertSame( 'cold', $registry->get_field( 'hp_listing', 'hp_instagram' )['zone'] ); - $instagram = $registry->get_field( 'hp_vendor', 'hp_instagram_url' ); - $this->assertSame( 'cold', $instagram['zone'] ); - - $whatsapp = $registry->get_field( 'hp_vendor', 'hp_whatsapp_url' ); - $this->assertSame( 'cold', $whatsapp['zone'] ); + $this->assertNull( $registry->get_field( 'hp_vendor', 'hp_instagram' ) ); + $this->assertNull( $registry->get_field( 'hp_vendor', 'hp_facebook_url' ) ); } - public function test_doctor_check_reports_field_count(): void { + public function test_registers_nothing_when_no_links_enabled(): void { + $registry = WPDO_Schema_Registry::instance(); + $this->adapter->on_register_fields( $registry ); + + $this->assertNull( $registry->get_field( 'hp_vendor', 'hp_facebook' ) ); + $this->assertNull( $registry->get_field( 'hp_listing', 'hp_facebook' ) ); + } + + public function test_doctor_check_reports_registered_count(): void { + update_option( 'hp_vendor_social_links', array( 'facebook', 'website' ) ); + update_option( 'hp_listing_social_links', array( 'instagram' ) ); + $result = $this->adapter->doctor_check(); + $this->assertTrue( $result['ok'] ); - $this->assertStringContainsString( '7 cold fields', $result['message'] ); + $this->assertStringContainsString( '3 cold fields', $result['message'] ); } public function test_score_aggregates_to_perfect_ten(): void {