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
This commit is contained in:
2026-09-25 22:35:30 +08:00
parent e443f20edb
commit d3ddbb8933
2 changed files with 62 additions and 45 deletions
@@ -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<int,string>
*/
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<string, array<int, string>> 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() ) ) ),
);
}
+27 -11
View File
@@ -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 {