2026-01-28 23:23:05 +01:00
|
|
|
<?php
|
|
|
|
|
/**
|
|
|
|
|
* AJAX handlers for frontend functionality.
|
|
|
|
|
*
|
|
|
|
|
* @package WP_FediStream
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
namespace WP_FediStream\Frontend;
|
|
|
|
|
|
2026-01-29 12:03:05 +01:00
|
|
|
use WP_FediStream\License\Manager as LicenseManager;
|
|
|
|
|
|
2026-01-28 23:23:05 +01:00
|
|
|
// Prevent direct file access.
|
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
|
|
|
exit;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Handles AJAX requests for the frontend.
|
|
|
|
|
*/
|
|
|
|
|
class Ajax {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Constructor.
|
|
|
|
|
*/
|
|
|
|
|
public function __construct() {
|
|
|
|
|
// Track data endpoint (public).
|
|
|
|
|
add_action( 'wp_ajax_fedistream_get_track', array( $this, 'get_track' ) );
|
|
|
|
|
add_action( 'wp_ajax_nopriv_fedistream_get_track', array( $this, 'get_track' ) );
|
|
|
|
|
|
|
|
|
|
// Record play endpoint (public).
|
|
|
|
|
add_action( 'wp_ajax_fedistream_record_play', array( $this, 'record_play' ) );
|
|
|
|
|
add_action( 'wp_ajax_nopriv_fedistream_record_play', array( $this, 'record_play' ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get track data via AJAX.
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function get_track(): void {
|
2026-01-29 12:03:05 +01:00
|
|
|
// Check license.
|
|
|
|
|
if ( ! LicenseManager::is_license_valid() ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'This feature requires a valid license.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 23:23:05 +01:00
|
|
|
// Verify nonce.
|
|
|
|
|
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ), 'wp-fedistream-nonce' ) ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'Invalid nonce.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$track_id = isset( $_POST['track_id'] ) ? absint( $_POST['track_id'] ) : 0;
|
|
|
|
|
|
|
|
|
|
if ( ! $track_id ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'Invalid track ID.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$track = get_post( $track_id );
|
|
|
|
|
|
|
|
|
|
if ( ! $track || 'fedistream_track' !== $track->post_type ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'Track not found.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check if track is published.
|
|
|
|
|
if ( 'publish' !== $track->post_status ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'Track not available.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get audio file.
|
|
|
|
|
$audio_id = get_post_meta( $track_id, '_fedistream_audio_file', true );
|
|
|
|
|
$audio_url = $audio_id ? wp_get_attachment_url( $audio_id ) : '';
|
|
|
|
|
|
|
|
|
|
if ( ! $audio_url ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'No audio file available.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get track metadata.
|
|
|
|
|
$thumbnail_id = get_post_thumbnail_id( $track_id );
|
|
|
|
|
$thumbnail = $thumbnail_id ? wp_get_attachment_image_url( $thumbnail_id, 'medium' ) : '';
|
|
|
|
|
|
|
|
|
|
// Get album info.
|
|
|
|
|
$album_id = get_post_meta( $track_id, '_fedistream_album_id', true );
|
|
|
|
|
$album = $album_id ? get_post( $album_id ) : null;
|
|
|
|
|
|
|
|
|
|
// Get artists.
|
|
|
|
|
$artist_ids = get_post_meta( $track_id, '_fedistream_artist_ids', true );
|
|
|
|
|
$artists = array();
|
|
|
|
|
|
|
|
|
|
if ( is_array( $artist_ids ) && ! empty( $artist_ids ) ) {
|
|
|
|
|
foreach ( $artist_ids as $artist_id ) {
|
|
|
|
|
$artist = get_post( $artist_id );
|
|
|
|
|
if ( $artist && 'fedistream_artist' === $artist->post_type ) {
|
|
|
|
|
$artists[] = array(
|
|
|
|
|
'id' => $artist->ID,
|
|
|
|
|
'name' => $artist->post_title,
|
|
|
|
|
'link' => get_permalink( $artist->ID ),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get duration.
|
|
|
|
|
$duration = get_post_meta( $track_id, '_fedistream_duration', true );
|
|
|
|
|
$duration_formatted = '';
|
|
|
|
|
if ( $duration ) {
|
|
|
|
|
$mins = floor( $duration / 60 );
|
|
|
|
|
$secs = $duration % 60;
|
|
|
|
|
$duration_formatted = $mins . ':' . str_pad( $secs, 2, '0', STR_PAD_LEFT );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$data = array(
|
|
|
|
|
'id' => $track->ID,
|
|
|
|
|
'title' => $track->post_title,
|
|
|
|
|
'permalink' => get_permalink( $track->ID ),
|
|
|
|
|
'audio_url' => $audio_url,
|
|
|
|
|
'thumbnail' => $thumbnail,
|
|
|
|
|
'artists' => $artists,
|
|
|
|
|
'artist' => ! empty( $artists ) ? $artists[0]['name'] : '',
|
|
|
|
|
'album' => $album ? $album->post_title : '',
|
|
|
|
|
'album_id' => $album ? $album->ID : 0,
|
|
|
|
|
'album_link' => $album ? get_permalink( $album->ID ) : '',
|
|
|
|
|
'duration' => $duration,
|
|
|
|
|
'duration_formatted' => $duration_formatted,
|
|
|
|
|
'explicit' => (bool) get_post_meta( $track_id, '_fedistream_explicit', true ),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
wp_send_json_success( $data );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Record a track play via AJAX.
|
|
|
|
|
*
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
public function record_play(): void {
|
2026-01-29 12:03:05 +01:00
|
|
|
// Check license.
|
|
|
|
|
if ( ! LicenseManager::is_license_valid() ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'This feature requires a valid license.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
2026-01-28 23:23:05 +01:00
|
|
|
// Verify nonce.
|
|
|
|
|
if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['nonce'] ), 'wp-fedistream-nonce' ) ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'Invalid nonce.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$track_id = isset( $_POST['track_id'] ) ? absint( $_POST['track_id'] ) : 0;
|
|
|
|
|
|
|
|
|
|
if ( ! $track_id ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'Invalid track ID.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$track = get_post( $track_id );
|
|
|
|
|
|
|
|
|
|
if ( ! $track || 'fedistream_track' !== $track->post_type ) {
|
|
|
|
|
wp_send_json_error( array( 'message' => __( 'Track not found.', 'wp-fedistream' ) ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
global $wpdb;
|
|
|
|
|
|
|
|
|
|
// Insert play record.
|
|
|
|
|
$table = $wpdb->prefix . 'fedistream_plays';
|
|
|
|
|
|
|
|
|
|
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
|
|
|
|
|
$wpdb->insert(
|
|
|
|
|
$table,
|
|
|
|
|
array(
|
|
|
|
|
'track_id' => $track_id,
|
|
|
|
|
'user_id' => get_current_user_id() ?: null,
|
|
|
|
|
'played_at' => current_time( 'mysql' ),
|
|
|
|
|
),
|
|
|
|
|
array( '%d', '%d', '%s' )
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Update play count in post meta.
|
|
|
|
|
$play_count = (int) get_post_meta( $track_id, '_fedistream_play_count', true );
|
|
|
|
|
update_post_meta( $track_id, '_fedistream_play_count', $play_count + 1 );
|
|
|
|
|
|
|
|
|
|
wp_send_json_success(
|
|
|
|
|
array(
|
|
|
|
|
'message' => __( 'Play recorded.', 'wp-fedistream' ),
|
|
|
|
|
'play_count' => $play_count + 1,
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|