fix(boundary): 核心不得無守衛呼叫 AddOn 的 TMDO_Listing_Stats
實機渲染時 Dashboard 分頁 fatal:"Class TMDO_Listing_Stats not found"。
該類別住在 hivepress-addon,核心有 6 處直呼,沒裝 AddOn 的站台會炸掉
Dashboard 與兩個 REST 端點(GET /listing/{id}、POST /listing/{id}/view)。
- TMDO_Zone_Warm 新增 VIEW_KEY / VIEW_TTL 常數(值與 AddOn 的
TMDO_Listing_Stats::VIEW_KEY 完全相同的 'wpdo_views',指向同一批列,
無資料遷移)
- CLI benchmark 改用核心常數
- REST 兩個 handler 改走新的 read_view_count() / bump_view_count():
AddOn 在場時仍委派過去(保留 hp_view_count postmeta fallback),
否則核心自己讀寫 warm 列
- wp tmdo cleanup --archive-expired 加守衛,AddOn 缺席時印 warning 並跳過
This commit is contained in:
@@ -798,12 +798,12 @@ class TMDO_CLI {
|
||||
if ( ! empty( $warm_posts ) ) {
|
||||
// Seed warm zone entries so reads are non-trivial.
|
||||
foreach ( $warm_posts as $pid ) {
|
||||
TMDO_Zone_Warm::set( (int) $pid, TMDO_Listing_Stats::VIEW_KEY, '1', DAY_IN_SECONDS );
|
||||
TMDO_Zone_Warm::set( (int) $pid, TMDO_Zone_Warm::VIEW_KEY, '1', DAY_IN_SECONDS );
|
||||
}
|
||||
|
||||
$start = microtime( true );
|
||||
foreach ( $warm_posts as $pid ) {
|
||||
TMDO_Zone_Warm::get( (int) $pid, TMDO_Listing_Stats::VIEW_KEY );
|
||||
TMDO_Zone_Warm::get( (int) $pid, TMDO_Zone_Warm::VIEW_KEY );
|
||||
}
|
||||
$warm_ms = ( microtime( true ) - $start ) * 1000;
|
||||
|
||||
@@ -1148,6 +1148,10 @@ class TMDO_CLI {
|
||||
WP_CLI::log( "Deleted {$warm_deleted} expired warm entries." );
|
||||
|
||||
if ( $archive_expired ) {
|
||||
// Listing archival is HivePress-specific and ships in that AddOn.
|
||||
if ( ! class_exists( 'TMDO_Listing_Stats' ) ) {
|
||||
WP_CLI::warning( '--archive-expired needs 2meet-data-optimizer-hivepress-addon; skipping.' );
|
||||
} else {
|
||||
WP_CLI::log( 'Archiving expired listing fields to Zone D...' );
|
||||
$archived = TMDO_Listing_Stats::archive_expired_listings();
|
||||
WP_CLI::log( "Archived {$archived} fields from expired listings." );
|
||||
@@ -1155,6 +1159,7 @@ class TMDO_CLI {
|
||||
$stats = TMDO_Zone_Archive::stats();
|
||||
WP_CLI::log( "Zone D total: {$stats['total_rows']} rows, {$stats['compressed_rows']} compressed." );
|
||||
}
|
||||
}
|
||||
|
||||
WP_CLI::success( 'Cleanup complete.' );
|
||||
}
|
||||
|
||||
@@ -646,7 +646,7 @@ class TMDO_REST_API {
|
||||
return $err;
|
||||
}
|
||||
|
||||
$views = TMDO_Listing_Stats::get_view_count( $post_id );
|
||||
$views = self::read_view_count( $post_id );
|
||||
|
||||
return new WP_REST_Response(
|
||||
array(
|
||||
@@ -730,8 +730,8 @@ class TMDO_REST_API {
|
||||
// Mark as counted for this IP/session.
|
||||
set_transient( $rl_key, 1, HOUR_IN_SECONDS );
|
||||
|
||||
TMDO_Listing_Stats::increment_view( $post_id );
|
||||
$views = TMDO_Listing_Stats::get_view_count( $post_id );
|
||||
self::bump_view_count( $post_id );
|
||||
$views = self::read_view_count( $post_id );
|
||||
|
||||
$response = new WP_REST_Response(
|
||||
array(
|
||||
@@ -1642,4 +1642,37 @@ class TMDO_REST_API {
|
||||
$result = TMDO_Migration_Orchestrator::resume();
|
||||
return new WP_REST_Response( $result, ! empty( $result['ok'] ) ? 200 : 409 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a post's view counter.
|
||||
*
|
||||
* Delegates to the HivePress AddOn when it is active, because that class
|
||||
* adds an hp_view_count postmeta fallback for listings migrated before the
|
||||
* warm zone existed. Without the AddOn — the normal case for a plain
|
||||
* install — core reads its own warm row directly. Calling the AddOn class
|
||||
* unconditionally used to fatal these endpoints on any site without it.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return int
|
||||
*/
|
||||
private static function read_view_count( int $post_id ): int {
|
||||
if ( class_exists( 'TMDO_Listing_Stats' ) ) {
|
||||
return (int) TMDO_Listing_Stats::get_view_count( $post_id );
|
||||
}
|
||||
return (int) ( TMDO_Zone_Warm::get( $post_id, TMDO_Zone_Warm::VIEW_KEY ) ?? 0 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment a post's view counter.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @return void
|
||||
*/
|
||||
private static function bump_view_count( int $post_id ): void {
|
||||
if ( class_exists( 'TMDO_Listing_Stats' ) ) {
|
||||
TMDO_Listing_Stats::increment_view( $post_id );
|
||||
return;
|
||||
}
|
||||
TMDO_Zone_Warm::increment( $post_id, TMDO_Zone_Warm::VIEW_KEY, 1, TMDO_Zone_Warm::VIEW_TTL );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,19 @@ if ( ! defined( 'ABSPATH' ) ) {
|
||||
*/
|
||||
class TMDO_Zone_Warm {
|
||||
|
||||
/**
|
||||
* Warm key used for per-post view counters.
|
||||
*
|
||||
* Owned by core because the row lives in this zone's table and core's admin,
|
||||
* CLI and REST layers all read it. The HivePress AddOn's
|
||||
* TMDO_Listing_Stats::VIEW_KEY carries the identical literal, so the two
|
||||
* address the same rows — nothing to migrate either way.
|
||||
*/
|
||||
const VIEW_KEY = 'wpdo_views';
|
||||
|
||||
/** TTL applied when core increments the view counter itself. */
|
||||
const VIEW_TTL = DAY_IN_SECONDS;
|
||||
|
||||
/**
|
||||
* Get the warm table name.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user