Files
2meet-data-optimizer-hivepr…/includes/interceptors/class-tmdo-statistics-interceptor.php
T
wpdev b4400a68e5 chore: initial snapshot of 2meet-data-optimizer-hivepress-addon 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
2026-07-31 05:06:36 +08:00

140 lines
3.7 KiB
PHP

<?php
/**
* Statistics interceptor for listing view tracking.
*
* @package WP_Data_Optimizer
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Statistics interceptor — tracks listing view events in hpct_statistics.
*
* Special: append-only (INSERT only, no UPDATE). Records events from
* both _hp_views meta update and HivePress listing/viewed action.
*/
class TMDO_Statistics_Interceptor extends TMDO_Interceptor_Base {
/**
* Module identifier.
*
* @var string
*/
protected string $module = 'statistics';
/**
* Registers WordPress hooks for this interceptor.
*
* @return void
*/
public function register_hooks(): void {
add_filter( 'update_post_metadata', array( $this, 'filter_view_meta' ), 10, 5 );
add_action( 'hivepress/v1/models/listing/viewed', array( $this, 'action_listing_viewed' ), 10, 1 );
add_action( 'before_delete_post', array( $this, 'action_delete_post' ), 10, 2 );
}
/**
* Filters update_post_metadata to record a view event when _hp_views is updated.
*
* @param mixed $check Whether to short-circuit.
* @param int $post_id Post ID.
* @param string $meta_key Meta key.
* @param mixed $meta_value Meta value.
* @param mixed $prev_value Previous meta value.
* @return mixed Filtered check value.
*/
public function filter_view_meta( $check, int $post_id, string $meta_key, $meta_value, $prev_value ) {
if ( '_hp_views' !== $meta_key || 'hp_listing' !== get_post_type( $post_id ) ) {
return $check;
}
if ( ! $this->is_active() ) {
return $check;
}
try {
$this->record_event( $post_id, 'view' );
} catch ( \Throwable $e ) {
TMDO_Logger::error( $this->module, 'update_post_metadata', $e->getMessage() );
}
return $check;
}
/**
* Records a view event when a HivePress listing is viewed.
*
* @param mixed $listing Listing object or ID.
* @return void
*/
public function action_listing_viewed( $listing ): void {
if ( ! $this->is_active() ) {
return;
}
$listing_id = is_object( $listing ) && method_exists( $listing, 'get_id' )
? $listing->get_id()
: ( is_numeric( $listing ) ? (int) $listing : 0 );
if ( ! $listing_id ) {
return;
}
try {
$this->record_event( $listing_id, 'hp_action_view' );
} catch ( \Throwable $e ) {
TMDO_Logger::error( $this->module, 'listing_viewed', $e->getMessage() );
}
}
/**
* Deletes statistics records when a listing post is deleted.
*
* @param int $post_id Post ID.
* @param \WP_Post $post Post object.
* @return void
*/
public function action_delete_post( int $post_id, \WP_Post $post ): void {
if ( 'hp_listing' !== $post->post_type || ! $this->is_active() ) {
return;
}
try {
global $wpdb;
$wpdb->delete( TMDO_DB::table( 'hpct_statistics' ), array( 'listing_id' => $post_id ), array( '%d' ) );
} catch ( \Throwable $e ) {
TMDO_Logger::error( $this->module, 'before_delete_post', $e->getMessage() );
}
}
/**
* Records a statistics event to the hpct_statistics table.
*
* @param int $listing_id Listing post ID.
* @param string $event_type Event type identifier.
* @return void
*/
private function record_event( int $listing_id, string $event_type ): void {
global $wpdb;
$user_id = get_current_user_id();
$ip = sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ?? '' ) );
$ip_hash = $ip ? hash( 'sha256', $ip ) : '';
$wpdb->insert(
TMDO_DB::table( 'hpct_statistics' ),
array(
'listing_id' => $listing_id,
'event_type' => $event_type,
'user_id' => $user_id,
'ip_hash' => $ip_hash,
'referrer' => substr( esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ?? '' ) ), 0, 500 ),
'created_at' => TMDO_DB::now(),
),
array( '%d', '%s', '%d', '%s', '%s', '%s' )
);
}
}