You've already forked wp-fedistream
All checks were successful
Create Release Package / build-release (push) Successful in 57s
The v0.4.1 fix was incomplete - shortcodes called get_*_data() methods directly, bypassing the recursion tracking in get_post_data(). Changes: - Added $in_shortcode_context flag to TemplateLoader - Added enter/exit_shortcode_context() methods - All shortcode render methods now enter context before data loading - When in shortcode context, the_content filter is always skipped This fully prevents infinite recursion when post content contains FediStream shortcodes that would otherwise recursively render. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
666 lines
24 KiB
PHP
666 lines
24 KiB
PHP
<?php
|
|
/**
|
|
* Template loader for frontend display.
|
|
*
|
|
* @package WP_FediStream
|
|
*/
|
|
|
|
namespace WP_FediStream\Frontend;
|
|
|
|
use WP_FediStream\Plugin;
|
|
|
|
// Prevent direct file access.
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
/**
|
|
* TemplateLoader class.
|
|
*
|
|
* Handles loading custom templates for FediStream post types.
|
|
*/
|
|
class TemplateLoader {
|
|
|
|
/**
|
|
* Recursion depth for get_post_data calls.
|
|
*
|
|
* @var int
|
|
*/
|
|
private static int $recursion_depth = 0;
|
|
|
|
/**
|
|
* Maximum allowed recursion depth.
|
|
*
|
|
* @var int
|
|
*/
|
|
private const MAX_RECURSION_DEPTH = 3;
|
|
|
|
/**
|
|
* Whether we're currently in a shortcode rendering context.
|
|
* When true, the_content filter is skipped to prevent recursive shortcode processing.
|
|
*
|
|
* @var bool
|
|
*/
|
|
private static bool $in_shortcode_context = false;
|
|
|
|
/**
|
|
* Enter shortcode rendering context.
|
|
* Call this before rendering shortcode content to prevent recursive shortcode processing.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function enter_shortcode_context(): void {
|
|
self::$in_shortcode_context = true;
|
|
}
|
|
|
|
/**
|
|
* Exit shortcode rendering context.
|
|
* Call this after shortcode rendering is complete.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function exit_shortcode_context(): void {
|
|
self::$in_shortcode_context = false;
|
|
}
|
|
|
|
/**
|
|
* Check if we're in a shortcode rendering context.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function is_in_shortcode_context(): bool {
|
|
return self::$in_shortcode_context;
|
|
}
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function __construct() {
|
|
add_filter( 'template_include', array( $this, 'template_include' ) );
|
|
add_filter( 'body_class', array( $this, 'body_class' ) );
|
|
}
|
|
|
|
/**
|
|
* Include custom templates for FediStream post types.
|
|
*
|
|
* @param string $template Template path.
|
|
* @return string Modified template path.
|
|
*/
|
|
public function template_include( string $template ): string {
|
|
// Check if we're on a FediStream page.
|
|
if ( is_singular( 'fedistream_artist' ) ) {
|
|
return $this->get_template( 'single-artist' );
|
|
}
|
|
|
|
if ( is_singular( 'fedistream_album' ) ) {
|
|
return $this->get_template( 'single-album' );
|
|
}
|
|
|
|
if ( is_singular( 'fedistream_track' ) ) {
|
|
return $this->get_template( 'single-track' );
|
|
}
|
|
|
|
if ( is_singular( 'fedistream_playlist' ) ) {
|
|
return $this->get_template( 'single-playlist' );
|
|
}
|
|
|
|
if ( is_post_type_archive( 'fedistream_artist' ) ) {
|
|
return $this->get_template( 'archive-artist' );
|
|
}
|
|
|
|
if ( is_post_type_archive( 'fedistream_album' ) ) {
|
|
return $this->get_template( 'archive-album' );
|
|
}
|
|
|
|
if ( is_post_type_archive( 'fedistream_track' ) ) {
|
|
return $this->get_template( 'archive-track' );
|
|
}
|
|
|
|
if ( is_post_type_archive( 'fedistream_playlist' ) ) {
|
|
return $this->get_template( 'archive-playlist' );
|
|
}
|
|
|
|
if ( is_tax( 'fedistream_genre' ) ) {
|
|
return $this->get_template( 'taxonomy-genre' );
|
|
}
|
|
|
|
if ( is_tax( 'fedistream_mood' ) ) {
|
|
return $this->get_template( 'taxonomy-mood' );
|
|
}
|
|
|
|
return $template;
|
|
}
|
|
|
|
/**
|
|
* Get template file path.
|
|
*
|
|
* First checks theme for override, then uses plugin template.
|
|
*
|
|
* @param string $template_name Template name without extension.
|
|
* @return string Template path.
|
|
*/
|
|
private function get_template( string $template_name ): string {
|
|
// Check theme for override.
|
|
$theme_template = locate_template(
|
|
array(
|
|
"fedistream/{$template_name}.php",
|
|
"fedistream/{$template_name}.twig",
|
|
)
|
|
);
|
|
|
|
if ( $theme_template ) {
|
|
return $theme_template;
|
|
}
|
|
|
|
// Use plugin template wrapper.
|
|
return WP_FEDISTREAM_PATH . 'includes/Frontend/template-wrapper.php';
|
|
}
|
|
|
|
/**
|
|
* Add FediStream classes to body.
|
|
*
|
|
* @param array $classes Body classes.
|
|
* @return array Modified classes.
|
|
*/
|
|
public function body_class( array $classes ): array {
|
|
if ( $this->is_fedistream_page() ) {
|
|
$classes[] = 'fedistream';
|
|
|
|
if ( is_singular( 'fedistream_artist' ) ) {
|
|
$classes[] = 'fedistream-artist';
|
|
$classes[] = 'fedistream-single';
|
|
} elseif ( is_singular( 'fedistream_album' ) ) {
|
|
$classes[] = 'fedistream-album';
|
|
$classes[] = 'fedistream-single';
|
|
} elseif ( is_singular( 'fedistream_track' ) ) {
|
|
$classes[] = 'fedistream-track';
|
|
$classes[] = 'fedistream-single';
|
|
} elseif ( is_singular( 'fedistream_playlist' ) ) {
|
|
$classes[] = 'fedistream-playlist';
|
|
$classes[] = 'fedistream-single';
|
|
} elseif ( is_post_type_archive( 'fedistream_artist' ) ) {
|
|
$classes[] = 'fedistream-archive';
|
|
$classes[] = 'fedistream-artists';
|
|
} elseif ( is_post_type_archive( 'fedistream_album' ) ) {
|
|
$classes[] = 'fedistream-archive';
|
|
$classes[] = 'fedistream-albums';
|
|
} elseif ( is_post_type_archive( 'fedistream_track' ) ) {
|
|
$classes[] = 'fedistream-archive';
|
|
$classes[] = 'fedistream-tracks';
|
|
} elseif ( is_post_type_archive( 'fedistream_playlist' ) ) {
|
|
$classes[] = 'fedistream-archive';
|
|
$classes[] = 'fedistream-playlists';
|
|
} elseif ( is_tax( 'fedistream_genre' ) || is_tax( 'fedistream_mood' ) ) {
|
|
$classes[] = 'fedistream-archive';
|
|
$classes[] = 'fedistream-taxonomy';
|
|
}
|
|
}
|
|
|
|
return $classes;
|
|
}
|
|
|
|
/**
|
|
* Check if current page is a FediStream page.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function is_fedistream_page(): bool {
|
|
return is_singular( array( 'fedistream_artist', 'fedistream_album', 'fedistream_track', 'fedistream_playlist' ) )
|
|
|| is_post_type_archive( array( 'fedistream_artist', 'fedistream_album', 'fedistream_track', 'fedistream_playlist' ) )
|
|
|| is_tax( array( 'fedistream_genre', 'fedistream_mood', 'fedistream_license' ) );
|
|
}
|
|
|
|
/**
|
|
* Get template context for current page.
|
|
*
|
|
* @return array Template context.
|
|
*/
|
|
public static function get_context(): array {
|
|
$context = array(
|
|
'site_name' => get_bloginfo( 'name' ),
|
|
'site_url' => home_url(),
|
|
'is_singular' => is_singular(),
|
|
'is_archive' => is_archive(),
|
|
'current_url' => get_permalink(),
|
|
);
|
|
|
|
if ( is_singular() ) {
|
|
global $post;
|
|
$context['post'] = self::get_post_data( $post );
|
|
}
|
|
|
|
if ( is_post_type_archive() || is_tax() ) {
|
|
$context['posts'] = self::get_archive_posts();
|
|
$context['pagination'] = self::get_pagination();
|
|
$context['archive_title'] = self::get_archive_title();
|
|
$context['archive_description'] = self::get_archive_description();
|
|
}
|
|
|
|
return $context;
|
|
}
|
|
|
|
/**
|
|
* Get post data for template.
|
|
*
|
|
* @param \WP_Post $post Post object.
|
|
* @param bool $skip_nested Whether to skip loading nested items (albums, tracks, etc.).
|
|
* @return array Post data.
|
|
*/
|
|
public static function get_post_data( \WP_Post $post, bool $skip_nested = false ): array {
|
|
// Track recursion to prevent infinite loops from shortcodes in content.
|
|
++self::$recursion_depth;
|
|
|
|
// Skip the_content filter if:
|
|
// 1. We're in a shortcode context (prevents recursive shortcode processing)
|
|
// 2. We're at depth > 1 (nested data loading)
|
|
$skip_content_filter = self::$in_shortcode_context || self::$recursion_depth > 1;
|
|
|
|
$data = array(
|
|
'id' => $post->ID,
|
|
'title' => get_the_title( $post ),
|
|
'content' => $skip_content_filter ? wp_kses_post( $post->post_content ) : apply_filters( 'the_content', $post->post_content ),
|
|
'excerpt' => get_the_excerpt( $post ),
|
|
'permalink' => get_permalink( $post ),
|
|
'thumbnail' => get_the_post_thumbnail_url( $post->ID, 'large' ),
|
|
'date' => get_the_date( '', $post ),
|
|
'author' => get_the_author_meta( 'display_name', $post->post_author ),
|
|
);
|
|
|
|
// Add post type specific data (skip nested items if at max depth).
|
|
$load_nested = ! $skip_nested && self::$recursion_depth < self::MAX_RECURSION_DEPTH;
|
|
|
|
switch ( $post->post_type ) {
|
|
case 'fedistream_artist':
|
|
$data = array_merge( $data, self::get_artist_data( $post->ID, $load_nested ) );
|
|
break;
|
|
case 'fedistream_album':
|
|
$data = array_merge( $data, self::get_album_data( $post->ID, $load_nested ) );
|
|
break;
|
|
case 'fedistream_track':
|
|
$data = array_merge( $data, self::get_track_data( $post->ID ) );
|
|
break;
|
|
case 'fedistream_playlist':
|
|
$data = array_merge( $data, self::get_playlist_data( $post->ID, $load_nested ) );
|
|
break;
|
|
}
|
|
|
|
// Add taxonomies.
|
|
$data['genres'] = self::get_terms( $post->ID, 'fedistream_genre' );
|
|
$data['moods'] = self::get_terms( $post->ID, 'fedistream_mood' );
|
|
|
|
--self::$recursion_depth;
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Get artist-specific data.
|
|
*
|
|
* @param int|\WP_Post $post_id Post ID or WP_Post object.
|
|
* @param bool $load_nested Whether to load nested albums.
|
|
* @return array Artist data.
|
|
*/
|
|
public static function get_artist_data( int|\WP_Post $post_id, bool $load_nested = true ): array {
|
|
// Support both post ID and WP_Post object.
|
|
if ( $post_id instanceof \WP_Post ) {
|
|
$post_id = $post_id->ID;
|
|
}
|
|
$type = get_post_meta( $post_id, '_fedistream_artist_type', true ) ?: 'solo';
|
|
$types = array(
|
|
'solo' => __( 'Solo Artist', 'wp-fedistream' ),
|
|
'band' => __( 'Band', 'wp-fedistream' ),
|
|
'duo' => __( 'Duo', 'wp-fedistream' ),
|
|
'collective' => __( 'Collective', 'wp-fedistream' ),
|
|
);
|
|
|
|
$albums = array();
|
|
$album_count = 0;
|
|
|
|
if ( $load_nested ) {
|
|
$album_posts = get_posts(
|
|
array(
|
|
'post_type' => 'fedistream_album',
|
|
'posts_per_page' => -1,
|
|
'post_status' => 'publish',
|
|
'meta_key' => '_fedistream_album_artist',
|
|
'meta_value' => $post_id,
|
|
'orderby' => 'meta_value',
|
|
'meta_query' => array(
|
|
array(
|
|
'key' => '_fedistream_album_release_date',
|
|
'compare' => 'EXISTS',
|
|
),
|
|
),
|
|
'order' => 'DESC',
|
|
)
|
|
);
|
|
$album_count = count( $album_posts );
|
|
$albums = array_map(
|
|
function ( $album ) {
|
|
return self::get_post_data( $album, true ); // Skip further nesting.
|
|
},
|
|
$album_posts
|
|
);
|
|
} else {
|
|
// Just get the count without loading full data.
|
|
$album_count = (int) get_posts(
|
|
array(
|
|
'post_type' => 'fedistream_album',
|
|
'posts_per_page' => -1,
|
|
'post_status' => 'publish',
|
|
'meta_key' => '_fedistream_album_artist',
|
|
'meta_value' => $post_id,
|
|
'fields' => 'ids',
|
|
)
|
|
);
|
|
$album_count = is_array( $album_count ) ? count( $album_count ) : 0;
|
|
}
|
|
|
|
return array(
|
|
'artist_type' => $type,
|
|
'artist_type_label' => $types[ $type ] ?? $types['solo'],
|
|
'formed_date' => get_post_meta( $post_id, '_fedistream_artist_formed_date', true ),
|
|
'location' => get_post_meta( $post_id, '_fedistream_artist_location', true ),
|
|
'website' => get_post_meta( $post_id, '_fedistream_artist_website', true ),
|
|
'social_links' => get_post_meta( $post_id, '_fedistream_artist_social_links', true ) ?: array(),
|
|
'members' => get_post_meta( $post_id, '_fedistream_artist_members', true ) ?: array(),
|
|
'albums' => $albums,
|
|
'album_count' => $album_count,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get album-specific data.
|
|
*
|
|
* @param int|\WP_Post $post_id Post ID or WP_Post object.
|
|
* @param bool $load_nested Whether to load nested tracks.
|
|
* @return array Album data.
|
|
*/
|
|
public static function get_album_data( int|\WP_Post $post_id, bool $load_nested = true ): array {
|
|
// Support both post ID and WP_Post object.
|
|
if ( $post_id instanceof \WP_Post ) {
|
|
$post_id = $post_id->ID;
|
|
}
|
|
$type = get_post_meta( $post_id, '_fedistream_album_type', true ) ?: 'album';
|
|
$types = array(
|
|
'album' => __( 'Album', 'wp-fedistream' ),
|
|
'ep' => __( 'EP', 'wp-fedistream' ),
|
|
'single' => __( 'Single', 'wp-fedistream' ),
|
|
'compilation' => __( 'Compilation', 'wp-fedistream' ),
|
|
'live' => __( 'Live Album', 'wp-fedistream' ),
|
|
'remix' => __( 'Remix Album', 'wp-fedistream' ),
|
|
);
|
|
$artist_id = get_post_meta( $post_id, '_fedistream_album_artist', true );
|
|
|
|
$tracks = array();
|
|
$total_tracks = 0;
|
|
|
|
if ( $load_nested ) {
|
|
$track_posts = get_posts(
|
|
array(
|
|
'post_type' => 'fedistream_track',
|
|
'posts_per_page' => -1,
|
|
'post_status' => 'publish',
|
|
'meta_key' => '_fedistream_track_album',
|
|
'meta_value' => $post_id,
|
|
'orderby' => 'meta_value_num',
|
|
'meta_query' => array(
|
|
'relation' => 'AND',
|
|
array(
|
|
'key' => '_fedistream_track_number',
|
|
'compare' => 'EXISTS',
|
|
),
|
|
),
|
|
'order' => 'ASC',
|
|
)
|
|
);
|
|
$total_tracks = count( $track_posts );
|
|
$tracks = array_map(
|
|
function ( $track ) {
|
|
return self::get_post_data( $track, true ); // Skip further nesting.
|
|
},
|
|
$track_posts
|
|
);
|
|
} else {
|
|
// Just get the count without loading full data.
|
|
$track_ids = get_posts(
|
|
array(
|
|
'post_type' => 'fedistream_track',
|
|
'posts_per_page' => -1,
|
|
'post_status' => 'publish',
|
|
'meta_key' => '_fedistream_track_album',
|
|
'meta_value' => $post_id,
|
|
'fields' => 'ids',
|
|
)
|
|
);
|
|
$total_tracks = is_array( $track_ids ) ? count( $track_ids ) : 0;
|
|
}
|
|
|
|
return array(
|
|
'album_type' => $type,
|
|
'album_type_label' => $types[ $type ] ?? $types['album'],
|
|
'release_date' => get_post_meta( $post_id, '_fedistream_album_release_date', true ),
|
|
'release_year' => date( 'Y', strtotime( get_post_meta( $post_id, '_fedistream_album_release_date', true ) ?: 'now' ) ),
|
|
'artist_id' => $artist_id,
|
|
'artist_name' => $artist_id ? get_the_title( $artist_id ) : '',
|
|
'artist_url' => $artist_id ? get_permalink( $artist_id ) : '',
|
|
'upc' => get_post_meta( $post_id, '_fedistream_album_upc', true ),
|
|
'catalog_number' => get_post_meta( $post_id, '_fedistream_album_catalog_number', true ),
|
|
'total_tracks' => $total_tracks,
|
|
'total_duration' => (int) get_post_meta( $post_id, '_fedistream_album_total_duration', true ),
|
|
'tracks' => $tracks,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get track-specific data.
|
|
*
|
|
* @param int|\WP_Post $post_id Post ID or WP_Post object.
|
|
* @return array Track data.
|
|
*/
|
|
public static function get_track_data( int|\WP_Post $post_id ): array {
|
|
// Support both post ID and WP_Post object.
|
|
if ( $post_id instanceof \WP_Post ) {
|
|
$post_id = $post_id->ID;
|
|
}
|
|
$album_id = get_post_meta( $post_id, '_fedistream_track_album', true );
|
|
$audio_file = get_post_meta( $post_id, '_fedistream_track_audio_file', true );
|
|
$artists = get_post_meta( $post_id, '_fedistream_track_artists', true ) ?: array();
|
|
$duration = (int) get_post_meta( $post_id, '_fedistream_track_duration', true );
|
|
|
|
$artist_data = array();
|
|
foreach ( $artists as $artist_id ) {
|
|
$artist = get_post( $artist_id );
|
|
if ( $artist ) {
|
|
$artist_data[] = array(
|
|
'id' => $artist_id,
|
|
'name' => $artist->post_title,
|
|
'url' => get_permalink( $artist_id ),
|
|
);
|
|
}
|
|
}
|
|
|
|
return array(
|
|
'track_number' => (int) get_post_meta( $post_id, '_fedistream_track_number', true ),
|
|
'disc_number' => (int) get_post_meta( $post_id, '_fedistream_track_disc_number', true ) ?: 1,
|
|
'duration' => $duration,
|
|
'duration_formatted' => $duration ? sprintf( '%d:%02d', floor( $duration / 60 ), $duration % 60 ) : '',
|
|
'audio_url' => $audio_file ? wp_get_attachment_url( $audio_file ) : '',
|
|
'audio_format' => get_post_meta( $post_id, '_fedistream_track_audio_format', true ),
|
|
'bpm' => (int) get_post_meta( $post_id, '_fedistream_track_bpm', true ),
|
|
'key' => get_post_meta( $post_id, '_fedistream_track_key', true ),
|
|
'explicit' => (bool) get_post_meta( $post_id, '_fedistream_track_explicit', true ),
|
|
'isrc' => get_post_meta( $post_id, '_fedistream_track_isrc', true ),
|
|
'album_id' => $album_id,
|
|
'album_title' => $album_id ? get_the_title( $album_id ) : '',
|
|
'album_url' => $album_id ? get_permalink( $album_id ) : '',
|
|
'album_artwork' => $album_id ? get_the_post_thumbnail_url( $album_id, 'medium' ) : '',
|
|
'artists' => $artist_data,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get playlist-specific data.
|
|
*
|
|
* @param int|\WP_Post $post_id Post ID or WP_Post object.
|
|
* @param bool $load_nested Whether to load nested tracks.
|
|
* @return array Playlist data.
|
|
*/
|
|
public static function get_playlist_data( int|\WP_Post $post_id, bool $load_nested = true ): array {
|
|
// Support both post ID and WP_Post object.
|
|
if ( $post_id instanceof \WP_Post ) {
|
|
$post_id = $post_id->ID;
|
|
}
|
|
global $wpdb;
|
|
|
|
$table = $wpdb->prefix . 'fedistream_playlist_tracks';
|
|
$duration = (int) get_post_meta( $post_id, '_fedistream_playlist_total_duration', true );
|
|
|
|
// Get track IDs.
|
|
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
|
|
$track_ids = $wpdb->get_col(
|
|
$wpdb->prepare(
|
|
"SELECT track_id FROM $table WHERE playlist_id = %d ORDER BY position ASC",
|
|
$post_id
|
|
)
|
|
);
|
|
|
|
$tracks = array();
|
|
$track_count = count( $track_ids );
|
|
|
|
if ( $load_nested && ! empty( $track_ids ) ) {
|
|
foreach ( $track_ids as $track_id ) {
|
|
$track = get_post( $track_id );
|
|
if ( $track && 'publish' === $track->post_status ) {
|
|
$tracks[] = self::get_post_data( $track, true ); // Skip further nesting.
|
|
}
|
|
}
|
|
}
|
|
|
|
return array(
|
|
'visibility' => get_post_meta( $post_id, '_fedistream_playlist_visibility', true ) ?: 'public',
|
|
'collaborative' => (bool) get_post_meta( $post_id, '_fedistream_playlist_collaborative', true ),
|
|
'federated' => (bool) get_post_meta( $post_id, '_fedistream_playlist_federated', true ),
|
|
'track_count' => $load_nested ? count( $tracks ) : $track_count,
|
|
'total_duration' => $duration,
|
|
'duration_formatted' => $duration >= 3600
|
|
? sprintf( '%d:%02d:%02d', floor( $duration / 3600 ), floor( ( $duration % 3600 ) / 60 ), $duration % 60 )
|
|
: sprintf( '%d:%02d', floor( $duration / 60 ), $duration % 60 ),
|
|
'tracks' => $tracks,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get taxonomy terms for post.
|
|
*
|
|
* @param int $post_id Post ID.
|
|
* @param string $taxonomy Taxonomy name.
|
|
* @return array Terms with name and URL.
|
|
*/
|
|
private static function get_terms( int $post_id, string $taxonomy ): array {
|
|
$terms = get_the_terms( $post_id, $taxonomy );
|
|
|
|
if ( ! $terms || is_wp_error( $terms ) ) {
|
|
return array();
|
|
}
|
|
|
|
return array_map(
|
|
function ( $term ) {
|
|
return array(
|
|
'id' => $term->term_id,
|
|
'name' => $term->name,
|
|
'slug' => $term->slug,
|
|
'url' => get_term_link( $term ),
|
|
);
|
|
},
|
|
$terms
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get archive posts.
|
|
*
|
|
* @return array Posts for archive.
|
|
*/
|
|
private static function get_archive_posts(): array {
|
|
global $wp_query;
|
|
|
|
$posts = array();
|
|
if ( $wp_query->have_posts() ) {
|
|
while ( $wp_query->have_posts() ) {
|
|
$wp_query->the_post();
|
|
$posts[] = self::get_post_data( get_post() );
|
|
}
|
|
wp_reset_postdata();
|
|
}
|
|
|
|
return $posts;
|
|
}
|
|
|
|
/**
|
|
* Get pagination data.
|
|
*
|
|
* @return array Pagination data.
|
|
*/
|
|
private static function get_pagination(): array {
|
|
global $wp_query;
|
|
|
|
$total_pages = $wp_query->max_num_pages;
|
|
$current = max( 1, get_query_var( 'paged' ) );
|
|
|
|
return array(
|
|
'total_pages' => $total_pages,
|
|
'current_page' => $current,
|
|
'has_prev' => $current > 1,
|
|
'has_next' => $current < $total_pages,
|
|
'prev_url' => $current > 1 ? get_pagenum_link( $current - 1 ) : '',
|
|
'next_url' => $current < $total_pages ? get_pagenum_link( $current + 1 ) : '',
|
|
'links' => paginate_links(
|
|
array(
|
|
'total' => $total_pages,
|
|
'current' => $current,
|
|
'type' => 'array',
|
|
'prev_text' => __( '« Previous', 'wp-fedistream' ),
|
|
'next_text' => __( 'Next »', 'wp-fedistream' ),
|
|
)
|
|
) ?: array(),
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Get archive title.
|
|
*
|
|
* @return string Archive title.
|
|
*/
|
|
private static function get_archive_title(): string {
|
|
if ( is_post_type_archive( 'fedistream_artist' ) ) {
|
|
return __( 'Artists', 'wp-fedistream' );
|
|
}
|
|
if ( is_post_type_archive( 'fedistream_album' ) ) {
|
|
return __( 'Albums', 'wp-fedistream' );
|
|
}
|
|
if ( is_post_type_archive( 'fedistream_track' ) ) {
|
|
return __( 'Tracks', 'wp-fedistream' );
|
|
}
|
|
if ( is_post_type_archive( 'fedistream_playlist' ) ) {
|
|
return __( 'Playlists', 'wp-fedistream' );
|
|
}
|
|
if ( is_tax() ) {
|
|
return single_term_title( '', false );
|
|
}
|
|
return get_the_archive_title();
|
|
}
|
|
|
|
/**
|
|
* Get archive description.
|
|
*
|
|
* @return string Archive description.
|
|
*/
|
|
private static function get_archive_description(): string {
|
|
if ( is_tax() ) {
|
|
return term_description();
|
|
}
|
|
return get_the_archive_description();
|
|
}
|
|
}
|