175 lines
4.0 KiB
PHP
175 lines
4.0 KiB
PHP
<?php
|
|
/**
|
|
* Analytics service.
|
|
*
|
|
* @package ModernAudioPlayer
|
|
*/
|
|
|
|
namespace ModernAudioPlayer;
|
|
|
|
defined( 'ABSPATH' ) || exit;
|
|
|
|
class Analytics {
|
|
/**
|
|
* Create database table on activation.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function create_table() {
|
|
global $wpdb;
|
|
|
|
$table_name = self::table_name();
|
|
$charset_collate = $wpdb->get_charset_collate();
|
|
|
|
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
|
|
|
$sql = "CREATE TABLE {$table_name} (
|
|
id bigint(20) unsigned NOT NULL AUTO_INCREMENT,
|
|
source_hash varchar(64) NOT NULL,
|
|
audio_src text NOT NULL,
|
|
track_title varchar(255) NOT NULL DEFAULT '',
|
|
play_count bigint(20) unsigned NOT NULL DEFAULT 0,
|
|
last_played datetime NULL DEFAULT NULL,
|
|
created_at datetime NOT NULL,
|
|
updated_at datetime NOT NULL,
|
|
PRIMARY KEY (id),
|
|
UNIQUE KEY source_hash (source_hash),
|
|
KEY play_count (play_count),
|
|
KEY last_played (last_played)
|
|
) {$charset_collate};";
|
|
|
|
dbDelta( $sql );
|
|
}
|
|
|
|
/**
|
|
* Get the analytics table name.
|
|
*
|
|
* @return string
|
|
*/
|
|
public static function table_name() {
|
|
global $wpdb;
|
|
return $wpdb->prefix . 'map_analytics';
|
|
}
|
|
|
|
/**
|
|
* Build a stable source hash.
|
|
*
|
|
* @param string $audio_src Audio URL.
|
|
* @return string
|
|
*/
|
|
public static function build_source_hash( $audio_src ) {
|
|
return hash( 'sha256', esc_url_raw( trim( (string) $audio_src ) ) );
|
|
}
|
|
|
|
/**
|
|
* Record a play.
|
|
*
|
|
* Count rule:
|
|
* One request counts once for the rendered player instance session. The frontend
|
|
* only sends this call on the first meaningful play event per player rendered on a page.
|
|
*
|
|
* @param string $audio_src Audio source URL.
|
|
* @param string $track_title Track title.
|
|
* @return bool
|
|
*/
|
|
public static function record_play( $audio_src, $track_title = '' ) {
|
|
global $wpdb;
|
|
|
|
$audio_src = esc_url_raw( $audio_src );
|
|
$track_title = sanitize_text_field( $track_title );
|
|
$source_hash = self::build_source_hash( $audio_src );
|
|
$table_name = self::table_name();
|
|
$current_time = current_time( 'mysql', true );
|
|
|
|
if ( empty( $audio_src ) ) {
|
|
return false;
|
|
}
|
|
|
|
$existing_id = $wpdb->get_var(
|
|
$wpdb->prepare(
|
|
"SELECT id FROM {$table_name} WHERE source_hash = %s LIMIT 1",
|
|
$source_hash
|
|
)
|
|
);
|
|
|
|
if ( $existing_id ) {
|
|
$result = $wpdb->query(
|
|
$wpdb->prepare(
|
|
"UPDATE {$table_name}
|
|
SET play_count = play_count + 1,
|
|
track_title = %s,
|
|
last_played = %s,
|
|
updated_at = %s
|
|
WHERE source_hash = %s",
|
|
$track_title,
|
|
$current_time,
|
|
$current_time,
|
|
$source_hash
|
|
)
|
|
);
|
|
|
|
return false !== $result;
|
|
}
|
|
|
|
$result = $wpdb->insert(
|
|
$table_name,
|
|
array(
|
|
'source_hash' => $source_hash,
|
|
'audio_src' => $audio_src,
|
|
'track_title' => $track_title,
|
|
'play_count' => 1,
|
|
'last_played' => $current_time,
|
|
'created_at' => $current_time,
|
|
'updated_at' => $current_time,
|
|
),
|
|
array( '%s', '%s', '%s', '%d', '%s', '%s', '%s' )
|
|
);
|
|
|
|
return false !== $result;
|
|
}
|
|
|
|
/**
|
|
* Fetch top tracks.
|
|
*
|
|
* @param int $limit Row limit.
|
|
* @return array<int, object>
|
|
*/
|
|
public static function get_top_tracks( $limit = 20 ) {
|
|
global $wpdb;
|
|
|
|
$table_name = self::table_name();
|
|
$limit = max( 1, absint( $limit ) );
|
|
|
|
return $wpdb->get_results(
|
|
$wpdb->prepare(
|
|
"SELECT source_hash, audio_src, track_title, play_count, last_played
|
|
FROM {$table_name}
|
|
ORDER BY play_count DESC, last_played DESC
|
|
LIMIT %d",
|
|
$limit
|
|
)
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get aggregate stats.
|
|
*
|
|
* @return array<string, int|string|null>
|
|
*/
|
|
public static function get_summary() {
|
|
global $wpdb;
|
|
|
|
$table_name = self::table_name();
|
|
$row = $wpdb->get_row(
|
|
"SELECT COUNT(*) AS track_count, COALESCE(SUM(play_count), 0) AS total_plays, MAX(last_played) AS last_played FROM {$table_name}",
|
|
ARRAY_A
|
|
);
|
|
|
|
return array(
|
|
'track_count' => isset( $row['track_count'] ) ? (int) $row['track_count'] : 0,
|
|
'total_plays' => isset( $row['total_plays'] ) ? (int) $row['total_plays'] : 0,
|
|
'last_played' => $row['last_played'] ?? null,
|
|
);
|
|
}
|
|
}
|