chore: initial snapshot of 2meet-data-optimizer v0.1.0
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
This commit is contained in:
@@ -0,0 +1,287 @@
|
||||
<?php
|
||||
/**
|
||||
* Central registry for zone field configurations.
|
||||
*
|
||||
* @package WP_Data_Optimizer
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Central registry for zone field configurations.
|
||||
*
|
||||
* Plugins register their meta_key → zone mappings here.
|
||||
* The registry drives table creation, migration, interceptors, and query routing.
|
||||
*
|
||||
* Usage:
|
||||
* $registry = TMDO_Schema_Registry::instance();
|
||||
* $registry->register( 'hivepress', [
|
||||
* 'post_type' => 'hp_listing',
|
||||
* 'meta_key' => 'hp_price',
|
||||
* 'zone' => 'hot',
|
||||
* 'data_type' => 'decimal(10,2) NOT NULL DEFAULT 0',
|
||||
* 'column' => 'hp_price',
|
||||
* 'indexed' => true,
|
||||
* ]);
|
||||
*/
|
||||
class TMDO_Schema_Registry {
|
||||
|
||||
/**
|
||||
* Singleton instance.
|
||||
*
|
||||
* @var self|null
|
||||
*/
|
||||
private static ?self $instance = null;
|
||||
|
||||
/**
|
||||
* Registered field mappings.
|
||||
*
|
||||
* Structure: [ 'post_type:meta_key' => field_config, ... ]
|
||||
*
|
||||
* @var array<string, array>
|
||||
*/
|
||||
private array $fields = array();
|
||||
|
||||
/**
|
||||
* Zone → post_type → columns map for Zone A (hot) table creation.
|
||||
*
|
||||
* @var array<string, array<string, array>>
|
||||
*/
|
||||
private array $hot_columns = array();
|
||||
|
||||
/**
|
||||
* Zone C (cold) fields grouped by post_type.
|
||||
*
|
||||
* @var array<string, string[]>
|
||||
*/
|
||||
private array $cold_fields = array();
|
||||
|
||||
/**
|
||||
* Zone B (warm) fields with TTL config.
|
||||
*
|
||||
* @var array<string, array>
|
||||
*/
|
||||
private array $warm_fields = array();
|
||||
|
||||
/**
|
||||
* Private constructor — use instance() to get the singleton.
|
||||
*/
|
||||
private function __construct() {}
|
||||
|
||||
/**
|
||||
* Get the singleton instance.
|
||||
*/
|
||||
public static function instance(): self {
|
||||
if ( null === self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a field mapping.
|
||||
*
|
||||
* @param string $provider Provider name (e.g. 'hivepress', 'woocommerce').
|
||||
* @param array $config Field configuration:
|
||||
* - post_type (string) WordPress post type.
|
||||
* - meta_key (string) The wp_postmeta meta_key.
|
||||
* - zone (string) hot|warm|cold|archive
|
||||
* - data_type (string) SQL column type for Zone A (e.g. 'decimal(10,2) NOT NULL DEFAULT 0').
|
||||
* - column (string) Column name in zone table (defaults to sanitized meta_key).
|
||||
* - indexed (bool) Whether to add an index (Zone A only).
|
||||
* - ttl (int) TTL in seconds (Zone B only, null = no expiry).
|
||||
* - cache_group (string) Object cache group (Zone C only).
|
||||
* - cache_ttl (int) Cache TTL in seconds (Zone C only).
|
||||
*/
|
||||
public function register( string $provider, array $config ): void {
|
||||
$config = wp_parse_args(
|
||||
$config,
|
||||
array(
|
||||
'post_type' => '',
|
||||
'entity_type' => '',
|
||||
'meta_key' => '',
|
||||
'zone' => 'hot',
|
||||
'data_type' => 'longtext',
|
||||
'column' => '',
|
||||
'indexed' => false,
|
||||
'ttl' => null,
|
||||
'cache_group' => '',
|
||||
'cache_ttl' => HOUR_IN_SECONDS,
|
||||
'provider' => $provider,
|
||||
)
|
||||
);
|
||||
|
||||
// v2.1.2 fix: normalize post_type vs entity_type. Some partner plugins
|
||||
// (e.g. 2meet-liff) register fields against entities other than posts
|
||||
// (user / term / comment) using `entity_type` instead of `post_type`.
|
||||
// Without normalization, those fields end up with empty-string post_type,
|
||||
// polluting `get_hot_post_types()` output. Use entity_type as bucket key.
|
||||
if ( empty( $config['post_type'] ) && ! empty( $config['entity_type'] ) ) {
|
||||
$config['post_type'] = sanitize_key( $config['entity_type'] );
|
||||
}
|
||||
|
||||
if ( empty( $config['column'] ) ) {
|
||||
$config['column'] = sanitize_key( $config['meta_key'] );
|
||||
}
|
||||
|
||||
$key = $config['post_type'] . ':' . $config['meta_key'];
|
||||
$config['provider'] = $provider;
|
||||
$this->fields[ $key ] = $config;
|
||||
|
||||
// Index by zone for efficient lookup.
|
||||
switch ( $config['zone'] ) {
|
||||
case 'hot':
|
||||
$this->hot_columns[ $config['post_type'] ][ $config['column'] ] = $config['data_type'];
|
||||
break;
|
||||
|
||||
case 'warm':
|
||||
$this->warm_fields[ $config['meta_key'] ] = $config;
|
||||
break;
|
||||
|
||||
case 'cold':
|
||||
$this->cold_fields[ $config['post_type'] ][] = $config['meta_key'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bulk register multiple fields.
|
||||
*
|
||||
* @param string $provider Provider name.
|
||||
* @param array $configs Array of field configs.
|
||||
*/
|
||||
public function register_many( string $provider, array $configs ): void {
|
||||
foreach ( $configs as $config ) {
|
||||
$this->register( $provider, $config );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the zone configuration for a specific field.
|
||||
*
|
||||
* @param string $post_type Post type.
|
||||
* @param string $meta_key Meta key.
|
||||
* @return array|null Field config or null if not registered.
|
||||
*/
|
||||
public function get_field( string $post_type, string $meta_key ): ?array {
|
||||
$key = $post_type . ':' . $meta_key;
|
||||
return $this->fields[ $key ] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all fields for a specific zone.
|
||||
*
|
||||
* @param string $zone Zone identifier (hot/warm/cold/archive).
|
||||
* @return array Array of field configs.
|
||||
*/
|
||||
public function get_zone_fields( string $zone ): array {
|
||||
return array_filter( $this->fields, fn( $f ) => $f['zone'] === $zone );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all fields for a specific zone and post type.
|
||||
*
|
||||
* @param string $zone Zone identifier.
|
||||
* @param string $post_type Post type.
|
||||
* @return array
|
||||
*/
|
||||
public function get_zone_fields_for_type( string $zone, string $post_type ): array {
|
||||
return array_filter(
|
||||
$this->fields,
|
||||
fn( $f ) => $f['zone'] === $zone && $f['post_type'] === $post_type
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hot column definitions for a post type (for table creation).
|
||||
*
|
||||
* @param string $post_type Post type.
|
||||
* @return array<string, string> Column name => SQL type.
|
||||
*/
|
||||
public function get_hot_columns( string $post_type ): array {
|
||||
return $this->hot_columns[ $post_type ] ?? array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all post types that have hot zone fields.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_hot_post_types(): array {
|
||||
return array_keys( $this->hot_columns );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all post types that have cold zone fields.
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public function get_cold_post_types(): array {
|
||||
return array_keys( $this->cold_fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cold field meta keys for a post type.
|
||||
*
|
||||
* @param string $post_type Post type.
|
||||
* @return string[] Array of meta keys.
|
||||
*/
|
||||
public function get_cold_meta_keys( string $post_type ): array {
|
||||
return array_unique( $this->cold_fields[ $post_type ] ?? array() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get warm field configuration.
|
||||
*
|
||||
* @param string $meta_key Meta key.
|
||||
* @return array|null
|
||||
*/
|
||||
public function get_warm_field( string $meta_key ): ?array {
|
||||
return $this->warm_fields[ $meta_key ] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check which zone a meta_key belongs to for a given post type.
|
||||
*
|
||||
* @param string $post_type Post type.
|
||||
* @param string $meta_key Meta key.
|
||||
* @return string|null Zone name or null if not registered.
|
||||
*/
|
||||
public function get_field_zone( string $post_type, string $meta_key ): ?string {
|
||||
$field = $this->get_field( $post_type, $meta_key );
|
||||
return $field['zone'] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all registered fields (for admin dashboard / analysis).
|
||||
*
|
||||
* @return array<string, array>
|
||||
*/
|
||||
public function all(): array {
|
||||
return $this->fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get summary statistics for the admin dashboard.
|
||||
*
|
||||
* @return array{hot: int, warm: int, cold: int, archive: int, total: int}
|
||||
*/
|
||||
public function get_stats(): array {
|
||||
$stats = array(
|
||||
'hot' => 0,
|
||||
'warm' => 0,
|
||||
'cold' => 0,
|
||||
'archive' => 0,
|
||||
'total' => 0,
|
||||
);
|
||||
foreach ( $this->fields as $field ) {
|
||||
if ( isset( $stats[ $field['zone'] ] ) ) {
|
||||
++$stats[ $field['zone'] ];
|
||||
}
|
||||
++$stats['total'];
|
||||
}
|
||||
return $stats;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user