d36bb954d1
Baseline before backporting wp-data-optimizer v3.0.1-v3.4.6. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TbG1keQQ7XBa7qMQY16KCY
488 lines
12 KiB
PHP
488 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* Post entity field registration for WP Data Optimizer (v2.9.1).
|
|
*
|
|
* Registers seven 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)
|
|
* hp_listing_core → wp_wpdo_post_hp_listing_core (hp_listing)
|
|
* hp_request_core → wp_wpdo_post_hp_request_core (hp_request)
|
|
* hp_vendor_core → wp_wpdo_post_hp_vendor_core (hp_vendor)
|
|
* 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 seven 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.
|
|
*
|
|
* 🔒 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
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* Registers seven 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_hp_listing_core_group();
|
|
self::register_hp_request_core_group();
|
|
self::register_hp_vendor_core_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',
|
|
),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* HivePress listing core meta keys (post_type=hp_listing).
|
|
* Aligns with the existing wpdo_hot_hp_listing flat table; v2.9.5 will
|
|
* copy-then-cutover the 230 dev10 rows to this group's table.
|
|
*
|
|
* @return void
|
|
*/
|
|
private static function register_hp_listing_core_group(): void {
|
|
TMDO_Entity_Registry::register_group(
|
|
'post',
|
|
'hp_listing_core',
|
|
array(
|
|
array(
|
|
'key' => 'hp_price',
|
|
'type' => 'decimal',
|
|
'searchable' => true,
|
|
'label' => 'Listing price',
|
|
),
|
|
array(
|
|
'key' => 'hp_status',
|
|
'type' => 'enum',
|
|
'searchable' => true,
|
|
'options' => array( 'publish', 'draft', 'pending', 'expired', 'private' ),
|
|
'label' => 'Listing status',
|
|
),
|
|
array(
|
|
'key' => 'hp_featured',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'Featured flag (0/1)',
|
|
),
|
|
array(
|
|
'key' => 'hp_verified',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'Verified flag (0/1)',
|
|
),
|
|
array(
|
|
'key' => 'hp_vendor',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'Vendor user ID',
|
|
),
|
|
array(
|
|
'key' => 'hp_expired_time',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'Expiry unix ts',
|
|
),
|
|
array(
|
|
'key' => 'hp_featured_time',
|
|
'type' => 'integer',
|
|
'label' => 'Featured-until unix ts',
|
|
),
|
|
array(
|
|
'key' => 'hp_view_count',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'View counter',
|
|
),
|
|
array(
|
|
'key' => 'hp_rating',
|
|
'type' => 'decimal',
|
|
'searchable' => true,
|
|
'label' => 'Average rating',
|
|
),
|
|
array(
|
|
'key' => 'hp_rating_count',
|
|
'type' => 'integer',
|
|
'label' => 'Rating count',
|
|
),
|
|
array(
|
|
'key' => 'hp_hourly_rate',
|
|
'type' => 'decimal',
|
|
'label' => 'Hourly rate',
|
|
),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* HivePress request core meta keys (post_type=hp_request).
|
|
*
|
|
* @return void
|
|
*/
|
|
private static function register_hp_request_core_group(): void {
|
|
TMDO_Entity_Registry::register_group(
|
|
'post',
|
|
'hp_request_core',
|
|
array(
|
|
array(
|
|
'key' => 'hp_status',
|
|
'type' => 'enum',
|
|
'searchable' => true,
|
|
'options' => array( 'publish', 'draft', 'pending', 'expired' ),
|
|
'label' => 'Request status',
|
|
),
|
|
array(
|
|
'key' => 'hp_user',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'Request author user ID',
|
|
),
|
|
array(
|
|
'key' => 'hp_expired_time',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'Expiry unix ts',
|
|
),
|
|
array(
|
|
'key' => 'hp_budget',
|
|
'type' => 'decimal',
|
|
'searchable' => true,
|
|
'label' => 'Budget amount',
|
|
),
|
|
array(
|
|
'key' => 'hp_view_count',
|
|
'type' => 'integer',
|
|
'label' => 'View counter',
|
|
),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* HivePress vendor core meta keys (post_type=hp_vendor).
|
|
*
|
|
* @return void
|
|
*/
|
|
private static function register_hp_vendor_core_group(): void {
|
|
TMDO_Entity_Registry::register_group(
|
|
'post',
|
|
'hp_vendor_core',
|
|
array(
|
|
array(
|
|
'key' => 'hp_user',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'Vendor user ID (linked WP user)',
|
|
),
|
|
array(
|
|
'key' => 'hp_verified',
|
|
'type' => 'integer',
|
|
'searchable' => true,
|
|
'label' => 'Verified flag (0/1)',
|
|
),
|
|
array(
|
|
'key' => 'hp_hourly_rate',
|
|
'type' => 'decimal',
|
|
'searchable' => true,
|
|
'label' => 'Hourly rate',
|
|
),
|
|
array(
|
|
'key' => 'hp_rating_count',
|
|
'type' => 'integer',
|
|
'label' => 'Rating count',
|
|
),
|
|
array(
|
|
'key' => 'hp_rating',
|
|
'type' => 'decimal',
|
|
'searchable' => true,
|
|
'label' => 'Average rating',
|
|
),
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* 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)',
|
|
),
|
|
)
|
|
);
|
|
}
|
|
}
|