Files
2meet-data-optimizer/includes/integrations/class-tmdo-post-fields.php
T
wpdev 1eedaa9b3c refactor(2meet-data-optimizer): stop registering HivePress entity groups in core
- Drop hp_listing_core / hp_request_core / hp_vendor_core from TMDO_Post_Fields and hp_user from TMDO_Member_Fields; the HivePress AddOn registers identical definitions (PR-019/020a/033b)
- Tests: core asserts it registers none of them; HP-specific core tests removed (covered by the AddOn); SyncBridgeEntityGuardTest registers its own hp_price group
- Verify: core unit 633 / integration 449, HP 145/49, WC 10/22 OK
- Deploy: activate the HivePress AddOn on dev20/21/22 first
- PR: PR-020b
2026-09-26 00:07:31 +08:00

320 lines
8.1 KiB
PHP

<?php
/**
* Post entity field registration for WP Data Optimizer (v2.9.1).
*
* Registers four post entity groups designed to absorb the bulk of
* wp_postmeta rows that previously bypassed any flat-table strategy.
* All groups use TMDO_Entity_Registry → flat tables instead of wp_postmeta EAV.
*
* Groups → flat tables (post_type targets):
* wp_core → wp_wpdo_post_wp_core (cross post_type)
* attachment → wp_wpdo_post_attachment (attachment)
* wc_product → wp_wpdo_post_wc_product (product)
* nav_menu_item → wp_wpdo_post_nav_menu_item (nav_menu_item)
*
* Pattern mirrors TMDO_Member_Fields::register(). Called from
* TMDO_Core::run() before the wpdo_register_entity_fields action fires;
* Schema_Manager materializes the four flat tables in init:1
* via process_pending_migrations() (idempotent via schema_hash compare).
*
* Keys not registered here (HivePress dynamic attrs, WPCS legacy keys,
* etc.) pass through to wp_postmeta unchanged — same fall-back behavior
* as user entity bridge.
*
* The HivePress groups (hp_listing_core / hp_request_core / hp_vendor_core)
* are registered by the HivePress AddOn (TMDO_HivePress_Entity_Groups).
*
* 🔒 v2.9.x frozen contract: this class must NEVER call register_group()
* with entity_type='user'. User entity registration is owned exclusively
* by TMDO_Member_Fields.
*
* @package WP_Data_Optimizer
* @since 2.9.1
*/
declare(strict_types=1);
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Registers four post entity groups.
*/
final class TMDO_Post_Fields {
/**
* Hook into WPDO entity field registration.
*
* @return void
*/
public static function register(): void {
add_action( 'wpdo_register_entity_fields', array( __CLASS__, 'register_entity_fields' ) );
}
/**
* Register all post entity groups.
*
* @return void
*/
public static function register_entity_fields(): void {
if ( ! class_exists( 'TMDO_Entity_Registry' ) ) {
return;
}
self::register_wp_core_group();
self::register_attachment_group();
self::register_wc_product_group();
self::register_nav_menu_item_group();
}
// ── Group definitions ────────────────────────────────────────────────────
/**
* WP core post meta keys present across post_types.
*
* @return void
*/
private static function register_wp_core_group(): void {
TMDO_Entity_Registry::register_group(
'post',
'wp_core',
array(
array(
'key' => '_thumbnail_id',
'type' => 'integer',
'searchable' => true,
'label' => 'Featured image attachment ID',
),
array(
'key' => '_wp_page_template',
'type' => 'text',
'label' => 'Page template slug',
),
array(
'key' => '_edit_last',
'type' => 'integer',
'searchable' => true,
'label' => 'Last editor user ID',
),
)
);
}
/**
* Attachment-specific meta keys (post_type=attachment).
*
* @return void
*/
private static function register_attachment_group(): void {
TMDO_Entity_Registry::register_group(
'post',
'attachment',
array(
array(
'key' => '_wp_attached_file',
'type' => 'text',
'searchable' => true,
'label' => 'Relative path of the attached file',
),
array(
'key' => '_wp_attachment_metadata',
'type' => 'json',
'label' => 'Image dimensions / EXIF / sizes array',
),
array(
'key' => '_wp_attachment_image_alt',
'type' => 'textarea',
'label' => 'Alt text for accessibility',
),
array(
'key' => '_wp_attachment_caption',
'type' => 'textarea',
'label' => 'Attachment caption',
),
)
);
}
/**
* WooCommerce product core meta keys (post_type=product).
* 19 keys — covers ~94% of wp_postmeta rows for products on dev10.
*
* @return void
*/
private static function register_wc_product_group(): void {
TMDO_Entity_Registry::register_group(
'post',
'wc_product',
array(
array(
'key' => '_price',
'type' => 'decimal',
'searchable' => true,
'label' => 'Effective price',
),
array(
'key' => '_regular_price',
'type' => 'decimal',
'searchable' => true,
'label' => 'Regular price',
),
array(
'key' => '_sale_price',
'type' => 'decimal',
'searchable' => true,
'label' => 'Sale price',
),
array(
'key' => '_stock',
'type' => 'integer',
'searchable' => true,
'label' => 'Stock quantity',
),
array(
'key' => '_stock_status',
'type' => 'enum',
'searchable' => true,
'options' => array( 'instock', 'outofstock', 'onbackorder' ),
'label' => 'Stock status',
),
array(
'key' => '_sku',
'type' => 'text',
'searchable' => true,
'label' => 'Product SKU',
),
array(
'key' => '_manage_stock',
'type' => 'enum',
'options' => array( 'yes', 'no' ),
'label' => 'Manage stock?',
),
array(
'key' => '_backorders',
'type' => 'enum',
'options' => array( 'yes', 'no', 'notify' ),
'label' => 'Allow backorders?',
),
array(
'key' => '_sold_individually',
'type' => 'enum',
'options' => array( 'yes', 'no' ),
'label' => 'Sold individually?',
),
array(
'key' => '_virtual',
'type' => 'enum',
'options' => array( 'yes', 'no' ),
'label' => 'Virtual product?',
),
array(
'key' => '_downloadable',
'type' => 'enum',
'options' => array( 'yes', 'no' ),
'label' => 'Downloadable?',
),
array(
'key' => '_tax_class',
'type' => 'text',
'label' => 'Tax class slug',
),
array(
'key' => '_tax_status',
'type' => 'enum',
'options' => array( 'taxable', 'shipping', 'none' ),
'label' => 'Tax status',
),
array(
'key' => '_download_limit',
'type' => 'integer',
'label' => 'Download limit',
),
array(
'key' => '_download_expiry',
'type' => 'integer',
'label' => 'Download expiry days',
),
array(
'key' => '_product_version',
'type' => 'text',
'label' => 'WC version product was created on',
),
array(
'key' => '_wc_average_rating',
'type' => 'decimal',
'searchable' => true,
'label' => 'Average rating',
),
array(
'key' => '_wc_review_count',
'type' => 'integer',
'label' => 'Review count',
),
array(
'key' => 'total_sales',
'type' => 'integer',
'searchable' => true,
'label' => 'Total sales count',
),
)
);
}
/**
* Nav menu item meta keys (post_type=nav_menu_item).
*
* @return void
*/
private static function register_nav_menu_item_group(): void {
TMDO_Entity_Registry::register_group(
'post',
'nav_menu_item',
array(
array(
'key' => '_menu_item_type',
'type' => 'enum',
'options' => array( 'post_type', 'taxonomy', 'custom', 'post_type_archive' ),
'label' => 'Menu item linking type',
),
array(
'key' => '_menu_item_menu_item_parent',
'type' => 'integer',
'label' => 'Parent menu item ID',
),
array(
'key' => '_menu_item_object_id',
'type' => 'integer',
'searchable' => true,
'label' => 'Linked object ID',
),
array(
'key' => '_menu_item_object',
'type' => 'text',
'label' => 'Linked object slug (post_type/taxonomy)',
),
array(
'key' => '_menu_item_target',
'type' => 'text',
'label' => 'Link target attribute',
),
array(
'key' => '_menu_item_classes',
'type' => 'json',
'label' => 'CSS classes array',
),
array(
'key' => '_menu_item_xfn',
'type' => 'text',
'label' => 'XFN relationship',
),
array(
'key' => '_menu_item_url',
'type' => 'textarea',
'label' => 'Custom URL (for type=custom)',
),
)
);
}
}