You've already forked wp-fedistream
feat: Initial release v0.1.0
WP FediStream - Stream music over ActivityPub Features: - Custom post types: Artist, Album, Track, Playlist - Custom taxonomies: Genre, Mood, License - User roles: Artist, Label - Admin dashboard with statistics - Frontend templates and shortcodes - Audio player with queue management - ActivityPub integration with actor support - WooCommerce product types for albums/tracks - User library with favorites and history - Notification system (in-app and email) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
794
includes/User/Library.php
Normal file
794
includes/User/Library.php
Normal file
@@ -0,0 +1,794 @@
|
||||
<?php
|
||||
/**
|
||||
* User Library class.
|
||||
*
|
||||
* @package WP_FediStream
|
||||
*/
|
||||
|
||||
namespace WP_FediStream\User;
|
||||
|
||||
// Prevent direct file access.
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles user library features (favorites, follows, history).
|
||||
*/
|
||||
class Library {
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_ajax_fedistream_toggle_favorite', array( $this, 'ajax_toggle_favorite' ) );
|
||||
add_action( 'wp_ajax_fedistream_toggle_follow', array( $this, 'ajax_toggle_follow' ) );
|
||||
add_action( 'wp_ajax_fedistream_get_library', array( $this, 'ajax_get_library' ) );
|
||||
add_action( 'wp_ajax_fedistream_get_followed_artists', array( $this, 'ajax_get_followed_artists' ) );
|
||||
add_action( 'wp_ajax_fedistream_get_history', array( $this, 'ajax_get_history' ) );
|
||||
add_action( 'wp_ajax_fedistream_clear_history', array( $this, 'ajax_clear_history' ) );
|
||||
|
||||
// Add library buttons to content.
|
||||
add_filter( 'fedistream_track_actions', array( $this, 'add_favorite_button' ), 10, 2 );
|
||||
add_filter( 'fedistream_album_actions', array( $this, 'add_favorite_button' ), 10, 2 );
|
||||
add_filter( 'fedistream_artist_actions', array( $this, 'add_follow_button' ), 10, 2 );
|
||||
|
||||
// Record play history.
|
||||
add_action( 'fedistream_track_played', array( $this, 'record_play_history' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle favorite via AJAX.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_toggle_favorite(): void {
|
||||
check_ajax_referer( 'fedistream_library', 'nonce' );
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( array( 'message' => __( 'You must be logged in.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
|
||||
$content_type = isset( $_POST['content_type'] ) ? sanitize_text_field( wp_unslash( $_POST['content_type'] ) ) : '';
|
||||
$content_id = isset( $_POST['content_id'] ) ? absint( $_POST['content_id'] ) : 0;
|
||||
|
||||
if ( ! in_array( $content_type, array( 'track', 'album', 'playlist' ), true ) || ! $content_id ) {
|
||||
wp_send_json_error( array( 'message' => __( 'Invalid request.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$is_favorited = self::is_favorited( $user_id, $content_type, $content_id );
|
||||
|
||||
if ( $is_favorited ) {
|
||||
$result = self::remove_favorite( $user_id, $content_type, $content_id );
|
||||
$action = 'removed';
|
||||
} else {
|
||||
$result = self::add_favorite( $user_id, $content_type, $content_id );
|
||||
$action = 'added';
|
||||
}
|
||||
|
||||
if ( $result ) {
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'action' => $action,
|
||||
'is_favorited' => ! $is_favorited,
|
||||
'message' => 'added' === $action
|
||||
? __( 'Added to your library.', 'wp-fedistream' )
|
||||
: __( 'Removed from your library.', 'wp-fedistream' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
wp_send_json_error( array( 'message' => __( 'Failed to update library.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle follow via AJAX.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_toggle_follow(): void {
|
||||
check_ajax_referer( 'fedistream_library', 'nonce' );
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( array( 'message' => __( 'You must be logged in.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
|
||||
$artist_id = isset( $_POST['artist_id'] ) ? absint( $_POST['artist_id'] ) : 0;
|
||||
|
||||
if ( ! $artist_id ) {
|
||||
wp_send_json_error( array( 'message' => __( 'Invalid artist.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$is_following = self::is_following( $user_id, $artist_id );
|
||||
|
||||
if ( $is_following ) {
|
||||
$result = self::unfollow_artist( $user_id, $artist_id );
|
||||
$action = 'unfollowed';
|
||||
} else {
|
||||
$result = self::follow_artist( $user_id, $artist_id );
|
||||
$action = 'followed';
|
||||
}
|
||||
|
||||
if ( $result ) {
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'action' => $action,
|
||||
'is_following' => ! $is_following,
|
||||
'message' => 'followed' === $action
|
||||
? __( 'You are now following this artist.', 'wp-fedistream' )
|
||||
: __( 'You unfollowed this artist.', 'wp-fedistream' ),
|
||||
)
|
||||
);
|
||||
} else {
|
||||
wp_send_json_error( array( 'message' => __( 'Failed to update follow status.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user library via AJAX.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_get_library(): void {
|
||||
check_ajax_referer( 'fedistream_library', 'nonce' );
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( array( 'message' => __( 'You must be logged in.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$type = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : 'all';
|
||||
$page = isset( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
|
||||
$per_page = 20;
|
||||
|
||||
$library = self::get_user_library( $user_id, $type, $page, $per_page );
|
||||
|
||||
wp_send_json_success( $library );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get followed artists via AJAX.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_get_followed_artists(): void {
|
||||
check_ajax_referer( 'fedistream_library', 'nonce' );
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( array( 'message' => __( 'You must be logged in.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$page = isset( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
|
||||
$per_page = 20;
|
||||
|
||||
$artists = self::get_followed_artists( $user_id, $page, $per_page );
|
||||
|
||||
wp_send_json_success( $artists );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get listening history via AJAX.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_get_history(): void {
|
||||
check_ajax_referer( 'fedistream_library', 'nonce' );
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( array( 'message' => __( 'You must be logged in.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$page = isset( $_POST['page'] ) ? absint( $_POST['page'] ) : 1;
|
||||
$per_page = 50;
|
||||
|
||||
$history = self::get_listening_history( $user_id, $page, $per_page );
|
||||
|
||||
wp_send_json_success( $history );
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear listening history via AJAX.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function ajax_clear_history(): void {
|
||||
check_ajax_referer( 'fedistream_library', 'nonce' );
|
||||
|
||||
if ( ! is_user_logged_in() ) {
|
||||
wp_send_json_error( array( 'message' => __( 'You must be logged in.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$result = self::clear_listening_history( $user_id );
|
||||
|
||||
if ( $result ) {
|
||||
wp_send_json_success( array( 'message' => __( 'History cleared.', 'wp-fedistream' ) ) );
|
||||
} else {
|
||||
wp_send_json_error( array( 'message' => __( 'Failed to clear history.', 'wp-fedistream' ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a favorite.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param string $content_type Content type (track, album, playlist).
|
||||
* @param int $content_id Content ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function add_favorite( int $user_id, string $content_type, int $content_id ): bool {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_favorites';
|
||||
|
||||
$result = $wpdb->insert(
|
||||
$table,
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'content_type' => $content_type,
|
||||
'content_id' => $content_id,
|
||||
'created_at' => current_time( 'mysql' ),
|
||||
),
|
||||
array( '%d', '%s', '%d', '%s' )
|
||||
);
|
||||
|
||||
if ( $result ) {
|
||||
do_action( 'fedistream_favorite_added', $user_id, $content_type, $content_id );
|
||||
}
|
||||
|
||||
return (bool) $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a favorite.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param string $content_type Content type (track, album, playlist).
|
||||
* @param int $content_id Content ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function remove_favorite( int $user_id, string $content_type, int $content_id ): bool {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_favorites';
|
||||
|
||||
$result = $wpdb->delete(
|
||||
$table,
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'content_type' => $content_type,
|
||||
'content_id' => $content_id,
|
||||
),
|
||||
array( '%d', '%s', '%d' )
|
||||
);
|
||||
|
||||
if ( $result ) {
|
||||
do_action( 'fedistream_favorite_removed', $user_id, $content_type, $content_id );
|
||||
}
|
||||
|
||||
return (bool) $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if content is favorited.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param string $content_type Content type.
|
||||
* @param int $content_id Content ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_favorited( int $user_id, string $content_type, int $content_id ): bool {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_favorites';
|
||||
|
||||
$exists = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT id FROM {$table} WHERE user_id = %d AND content_type = %s AND content_id = %d",
|
||||
$user_id,
|
||||
$content_type,
|
||||
$content_id
|
||||
)
|
||||
);
|
||||
|
||||
return (bool) $exists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Follow an artist.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param int $artist_id Artist post ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function follow_artist( int $user_id, int $artist_id ): bool {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_user_follows';
|
||||
|
||||
$result = $wpdb->insert(
|
||||
$table,
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'artist_id' => $artist_id,
|
||||
'created_at' => current_time( 'mysql' ),
|
||||
),
|
||||
array( '%d', '%d', '%s' )
|
||||
);
|
||||
|
||||
if ( $result ) {
|
||||
do_action( 'fedistream_artist_followed', $user_id, $artist_id );
|
||||
}
|
||||
|
||||
return (bool) $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unfollow an artist.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param int $artist_id Artist post ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function unfollow_artist( int $user_id, int $artist_id ): bool {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_user_follows';
|
||||
|
||||
$result = $wpdb->delete(
|
||||
$table,
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'artist_id' => $artist_id,
|
||||
),
|
||||
array( '%d', '%d' )
|
||||
);
|
||||
|
||||
if ( $result ) {
|
||||
do_action( 'fedistream_artist_unfollowed', $user_id, $artist_id );
|
||||
}
|
||||
|
||||
return (bool) $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user is following an artist.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param int $artist_id Artist post ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_following( int $user_id, int $artist_id ): bool {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_user_follows';
|
||||
|
||||
$exists = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT id FROM {$table} WHERE user_id = %d AND artist_id = %d",
|
||||
$user_id,
|
||||
$artist_id
|
||||
)
|
||||
);
|
||||
|
||||
return (bool) $exists;
|
||||
}
|
||||
|
||||
/**
|
||||
* Record play history.
|
||||
*
|
||||
* @param int $track_id Track post ID.
|
||||
* @param int $user_id User ID (0 for anonymous).
|
||||
* @return void
|
||||
*/
|
||||
public function record_play_history( int $track_id, int $user_id ): void {
|
||||
if ( ! $user_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_listening_history';
|
||||
|
||||
// Check if recently played (within last 30 seconds) to avoid duplicates.
|
||||
$recent = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT id FROM {$table} WHERE user_id = %d AND track_id = %d AND played_at > DATE_SUB(NOW(), INTERVAL 30 SECOND)",
|
||||
$user_id,
|
||||
$track_id
|
||||
)
|
||||
);
|
||||
|
||||
if ( $recent ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$wpdb->insert(
|
||||
$table,
|
||||
array(
|
||||
'user_id' => $user_id,
|
||||
'track_id' => $track_id,
|
||||
'played_at' => current_time( 'mysql' ),
|
||||
),
|
||||
array( '%d', '%d', '%s' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user library.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param string $type Content type filter (all, tracks, albums, playlists).
|
||||
* @param int $page Page number.
|
||||
* @param int $per_page Items per page.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_user_library( int $user_id, string $type = 'all', int $page = 1, int $per_page = 20 ): array {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_favorites';
|
||||
$offset = ( $page - 1 ) * $per_page;
|
||||
|
||||
$where = 'WHERE user_id = %d';
|
||||
$params = array( $user_id );
|
||||
|
||||
if ( 'all' !== $type && in_array( $type, array( 'track', 'album', 'playlist' ), true ) ) {
|
||||
$where .= ' AND content_type = %s';
|
||||
$params[] = $type;
|
||||
}
|
||||
|
||||
$total = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$table} {$where}",
|
||||
...$params
|
||||
)
|
||||
);
|
||||
|
||||
$params[] = $per_page;
|
||||
$params[] = $offset;
|
||||
|
||||
$favorites = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT content_type, content_id, created_at FROM {$table} {$where} ORDER BY created_at DESC LIMIT %d OFFSET %d",
|
||||
...$params
|
||||
)
|
||||
);
|
||||
|
||||
$items = array();
|
||||
|
||||
foreach ( $favorites as $favorite ) {
|
||||
$post = get_post( $favorite->content_id );
|
||||
|
||||
if ( ! $post || 'publish' !== $post->post_status ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item = array(
|
||||
'id' => $post->ID,
|
||||
'type' => $favorite->content_type,
|
||||
'title' => $post->post_title,
|
||||
'permalink' => get_permalink( $post ),
|
||||
'added_at' => $favorite->created_at,
|
||||
'thumbnail' => get_the_post_thumbnail_url( $post, 'medium' ),
|
||||
);
|
||||
|
||||
if ( 'track' === $favorite->content_type ) {
|
||||
$item['duration'] = get_post_meta( $post->ID, '_fedistream_duration', true );
|
||||
$item['artist'] = self::get_track_artist_name( $post->ID );
|
||||
} elseif ( 'album' === $favorite->content_type ) {
|
||||
$item['artist'] = self::get_album_artist_name( $post->ID );
|
||||
$item['track_count'] = get_post_meta( $post->ID, '_fedistream_total_tracks', true );
|
||||
}
|
||||
|
||||
$items[] = $item;
|
||||
}
|
||||
|
||||
return array(
|
||||
'items' => $items,
|
||||
'total' => (int) $total,
|
||||
'page' => $page,
|
||||
'per_page' => $per_page,
|
||||
'total_pages' => (int) ceil( $total / $per_page ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get followed artists.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param int $page Page number.
|
||||
* @param int $per_page Items per page.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_followed_artists( int $user_id, int $page = 1, int $per_page = 20 ): array {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_user_follows';
|
||||
$offset = ( $page - 1 ) * $per_page;
|
||||
|
||||
$total = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$table} WHERE user_id = %d",
|
||||
$user_id
|
||||
)
|
||||
);
|
||||
|
||||
$follows = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT artist_id, created_at FROM {$table} WHERE user_id = %d ORDER BY created_at DESC LIMIT %d OFFSET %d",
|
||||
$user_id,
|
||||
$per_page,
|
||||
$offset
|
||||
)
|
||||
);
|
||||
|
||||
$artists = array();
|
||||
|
||||
foreach ( $follows as $follow ) {
|
||||
$post = get_post( $follow->artist_id );
|
||||
|
||||
if ( ! $post || 'publish' !== $post->post_status ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$artists[] = array(
|
||||
'id' => $post->ID,
|
||||
'name' => $post->post_title,
|
||||
'permalink' => get_permalink( $post ),
|
||||
'followed_at' => $follow->created_at,
|
||||
'thumbnail' => get_the_post_thumbnail_url( $post, 'thumbnail' ),
|
||||
'type' => get_post_meta( $post->ID, '_fedistream_artist_type', true ) ?: 'solo',
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'artists' => $artists,
|
||||
'total' => (int) $total,
|
||||
'page' => $page,
|
||||
'per_page' => $per_page,
|
||||
'total_pages' => (int) ceil( $total / $per_page ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get listening history.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param int $page Page number.
|
||||
* @param int $per_page Items per page.
|
||||
* @return array
|
||||
*/
|
||||
public static function get_listening_history( int $user_id, int $page = 1, int $per_page = 50 ): array {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_listening_history';
|
||||
$offset = ( $page - 1 ) * $per_page;
|
||||
|
||||
$total = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$table} WHERE user_id = %d",
|
||||
$user_id
|
||||
)
|
||||
);
|
||||
|
||||
$history = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT track_id, played_at FROM {$table} WHERE user_id = %d ORDER BY played_at DESC LIMIT %d OFFSET %d",
|
||||
$user_id,
|
||||
$per_page,
|
||||
$offset
|
||||
)
|
||||
);
|
||||
|
||||
$tracks = array();
|
||||
|
||||
foreach ( $history as $item ) {
|
||||
$post = get_post( $item->track_id );
|
||||
|
||||
if ( ! $post || 'publish' !== $post->post_status ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tracks[] = array(
|
||||
'id' => $post->ID,
|
||||
'title' => $post->post_title,
|
||||
'permalink' => get_permalink( $post ),
|
||||
'played_at' => $item->played_at,
|
||||
'thumbnail' => get_the_post_thumbnail_url( $post, 'thumbnail' ),
|
||||
'duration' => get_post_meta( $post->ID, '_fedistream_duration', true ),
|
||||
'artist' => self::get_track_artist_name( $post->ID ),
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'tracks' => $tracks,
|
||||
'total' => (int) $total,
|
||||
'page' => $page,
|
||||
'per_page' => $per_page,
|
||||
'total_pages' => (int) ceil( $total / $per_page ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear listening history.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @return bool
|
||||
*/
|
||||
public static function clear_listening_history( int $user_id ): bool {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_listening_history';
|
||||
$result = $wpdb->delete( $table, array( 'user_id' => $user_id ), array( '%d' ) );
|
||||
|
||||
return false !== $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get track artist name.
|
||||
*
|
||||
* @param int $track_id Track post ID.
|
||||
* @return string
|
||||
*/
|
||||
private static function get_track_artist_name( int $track_id ): string {
|
||||
$artist_ids = get_post_meta( $track_id, '_fedistream_artist_ids', true );
|
||||
|
||||
if ( is_array( $artist_ids ) && ! empty( $artist_ids ) ) {
|
||||
$names = array();
|
||||
foreach ( $artist_ids as $artist_id ) {
|
||||
$artist = get_post( $artist_id );
|
||||
if ( $artist ) {
|
||||
$names[] = $artist->post_title;
|
||||
}
|
||||
}
|
||||
return implode( ', ', $names );
|
||||
}
|
||||
|
||||
$album_id = get_post_meta( $track_id, '_fedistream_album_id', true );
|
||||
$artist_id = $album_id ? get_post_meta( $album_id, '_fedistream_album_artist', true ) : 0;
|
||||
|
||||
if ( $artist_id ) {
|
||||
$artist = get_post( $artist_id );
|
||||
return $artist ? $artist->post_title : '';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get album artist name.
|
||||
*
|
||||
* @param int $album_id Album post ID.
|
||||
* @return string
|
||||
*/
|
||||
private static function get_album_artist_name( int $album_id ): string {
|
||||
$artist_id = get_post_meta( $album_id, '_fedistream_album_artist', true );
|
||||
|
||||
if ( $artist_id ) {
|
||||
$artist = get_post( $artist_id );
|
||||
return $artist ? $artist->post_title : '';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add favorite button to track/album actions.
|
||||
*
|
||||
* @param string $actions HTML actions.
|
||||
* @param int $post_id Post ID.
|
||||
* @return string
|
||||
*/
|
||||
public function add_favorite_button( string $actions, int $post_id ): string {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
return $actions;
|
||||
}
|
||||
|
||||
$post = get_post( $post_id );
|
||||
if ( ! $post ) {
|
||||
return $actions;
|
||||
}
|
||||
|
||||
$content_type = str_replace( 'fedistream_', '', $post->post_type );
|
||||
$user_id = get_current_user_id();
|
||||
$is_favorited = self::is_favorited( $user_id, $content_type, $post_id );
|
||||
|
||||
$button = sprintf(
|
||||
'<button class="fedistream-favorite-btn%s" data-content-type="%s" data-content-id="%d" title="%s">
|
||||
<span class="dashicons dashicons-heart"></span>
|
||||
</button>',
|
||||
$is_favorited ? ' is-favorited' : '',
|
||||
esc_attr( $content_type ),
|
||||
$post_id,
|
||||
$is_favorited ? esc_attr__( 'Remove from library', 'wp-fedistream' ) : esc_attr__( 'Add to library', 'wp-fedistream' )
|
||||
);
|
||||
|
||||
return $actions . $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add follow button to artist actions.
|
||||
*
|
||||
* @param string $actions HTML actions.
|
||||
* @param int $artist_id Artist post ID.
|
||||
* @return string
|
||||
*/
|
||||
public function add_follow_button( string $actions, int $artist_id ): string {
|
||||
if ( ! is_user_logged_in() ) {
|
||||
return $actions;
|
||||
}
|
||||
|
||||
$user_id = get_current_user_id();
|
||||
$is_following = self::is_following( $user_id, $artist_id );
|
||||
|
||||
$button = sprintf(
|
||||
'<button class="fedistream-follow-btn%s" data-artist-id="%d">
|
||||
<span class="dashicons dashicons-%s"></span>
|
||||
<span class="button-text">%s</span>
|
||||
</button>',
|
||||
$is_following ? ' is-following' : '',
|
||||
$artist_id,
|
||||
$is_following ? 'yes' : 'plus',
|
||||
$is_following ? esc_html__( 'Following', 'wp-fedistream' ) : esc_html__( 'Follow', 'wp-fedistream' )
|
||||
);
|
||||
|
||||
return $actions . $button;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's favorite count.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @param string $content_type Optional content type filter.
|
||||
* @return int
|
||||
*/
|
||||
public static function get_favorite_count( int $user_id, string $content_type = '' ): int {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_favorites';
|
||||
|
||||
if ( $content_type ) {
|
||||
$count = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$table} WHERE user_id = %d AND content_type = %s",
|
||||
$user_id,
|
||||
$content_type
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$count = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$table} WHERE user_id = %d",
|
||||
$user_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return (int) $count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get user's followed artist count.
|
||||
*
|
||||
* @param int $user_id User ID.
|
||||
* @return int
|
||||
*/
|
||||
public static function get_following_count( int $user_id ): int {
|
||||
global $wpdb;
|
||||
|
||||
$table = $wpdb->prefix . 'fedistream_user_follows';
|
||||
|
||||
$count = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$table} WHERE user_id = %d",
|
||||
$user_id
|
||||
)
|
||||
);
|
||||
|
||||
return (int) $count;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user