__( '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 { // 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, ) ); } }