b4400a68e5
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
142 lines
4.1 KiB
PHP
142 lines
4.1 KiB
PHP
<?php
|
|
/**
|
|
* 8-dimension anti-EAV suitability scorer (aggregate across all adapters).
|
|
*
|
|
* Each adapter self-reports an 8-D score via `suitability_score()`. This
|
|
* scorer collects all reports from `TMDO_HivePress_Bootstrap::adapters()`
|
|
* and computes:
|
|
*
|
|
* - Per-adapter aggregate (already in adapter's own report)
|
|
* - Per-dimension average across all adapters
|
|
* - Site-wide aggregate (mean of all adapter aggregates)
|
|
*
|
|
* The output feeds:
|
|
* - `wp wpdo hivepress score` CLI (Sprint 4)
|
|
* - Admin UI HivePress tab (Sprint 4)
|
|
* - REST endpoint /wpdo/v1/hivepress/score (Sprint 4)
|
|
*
|
|
* Per Karpathy guideline: a sum/avg, not a fancy weighted model. If the
|
|
* score needs to be more sophisticated later, tradeoff it then.
|
|
*
|
|
* @package WP_Data_Optimizer
|
|
* @since 3.0.0
|
|
*/
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
if ( ! class_exists( 'TMDO_HivePress_Suitability_Scorer' ) ) {
|
|
|
|
/**
|
|
* Aggregate scorer for active HivePress adapters.
|
|
*
|
|
* Stateless — every call rebuilds the report from current adapter state.
|
|
*/
|
|
final class TMDO_HivePress_Suitability_Scorer {
|
|
|
|
/** Dimension keys (must match adapter `suitability_score()` output). */
|
|
public const DIMENSIONS = array(
|
|
'd1_meta_calls',
|
|
'd2_meta_sql',
|
|
'd3_table_coverage',
|
|
'd4_registry_meta',
|
|
'd5_hook_bus',
|
|
'd6_options',
|
|
'd7_coupling',
|
|
'd8_perf',
|
|
);
|
|
|
|
/**
|
|
* Build a complete score report for all currently active adapters.
|
|
*
|
|
* @return array{adapters:array<string,array<string,float>>, per_dimension:array<string,float>, aggregate:float, adapter_count:int}
|
|
*/
|
|
public static function report(): array {
|
|
$adapters = class_exists( 'TMDO_HivePress_Bootstrap' )
|
|
? TMDO_HivePress_Bootstrap::adapters()
|
|
: array();
|
|
|
|
$per_adapter = array();
|
|
foreach ( $adapters as $slug => $adapter ) {
|
|
if ( $adapter instanceof TMDO_HivePress_Adapter ) {
|
|
$per_adapter[ $slug ] = $adapter->suitability_score();
|
|
}
|
|
}
|
|
|
|
return array(
|
|
'adapters' => $per_adapter,
|
|
'per_dimension' => self::compute_per_dimension( $per_adapter ),
|
|
'aggregate' => self::compute_aggregate( $per_adapter ),
|
|
'adapter_count' => count( $per_adapter ),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Compute the per-dimension average across all adapter reports.
|
|
*
|
|
* @param array<string,array<string,float>> $per_adapter Adapter score map.
|
|
* @return array<string,float> Dimension key → average value.
|
|
*/
|
|
public static function compute_per_dimension( array $per_adapter ): array {
|
|
$out = array();
|
|
if ( empty( $per_adapter ) ) {
|
|
foreach ( self::DIMENSIONS as $d ) {
|
|
$out[ $d ] = 0.0;
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
foreach ( self::DIMENSIONS as $d ) {
|
|
$sum = 0.0;
|
|
foreach ( $per_adapter as $score ) {
|
|
$sum += (float) ( $score[ $d ] ?? 0.0 );
|
|
}
|
|
$out[ $d ] = round( $sum / count( $per_adapter ), 2 );
|
|
}
|
|
return $out;
|
|
}
|
|
|
|
/**
|
|
* Compute the site-wide aggregate (mean of adapter aggregates).
|
|
*
|
|
* @param array<string,array<string,float>> $per_adapter Adapter score map.
|
|
*/
|
|
public static function compute_aggregate( array $per_adapter ): float {
|
|
if ( empty( $per_adapter ) ) {
|
|
return 0.0;
|
|
}
|
|
$sum = 0.0;
|
|
foreach ( $per_adapter as $score ) {
|
|
$sum += (float) ( $score['aggregate'] ?? 0.0 );
|
|
}
|
|
return round( $sum / count( $per_adapter ), 2 );
|
|
}
|
|
|
|
/**
|
|
* Identify which dimensions are dragging the aggregate down.
|
|
*
|
|
* Returns adapter slugs whose given dimension is below the threshold.
|
|
*
|
|
* @param string $dimension Dimension key (e.g. 'd8_perf').
|
|
* @param float $threshold Minimum acceptable value (default 1.0).
|
|
* @return array<int,string> Slugs needing attention for this dimension.
|
|
*/
|
|
public static function adapters_below_threshold( string $dimension, float $threshold = 1.0 ): array {
|
|
if ( ! in_array( $dimension, self::DIMENSIONS, true ) ) {
|
|
return array();
|
|
}
|
|
|
|
$report = self::report();
|
|
$flagged = array();
|
|
foreach ( $report['adapters'] as $slug => $score ) {
|
|
if ( ( (float) ( $score[ $dimension ] ?? 0.0 ) ) < $threshold ) {
|
|
$flagged[] = $slug;
|
|
}
|
|
}
|
|
return $flagged;
|
|
}
|
|
}
|
|
|
|
} // end if ( ! class_exists )
|