diff --git a/includes/functions/_helpers-query.php b/includes/functions/_helpers-query.php
index 837b5f5a..06e41209 100644
--- a/includes/functions/_helpers-query.php
+++ b/includes/functions/_helpers-query.php
@@ -867,3 +867,73 @@ if ( ! function_exists( 'fictioneer_sql_get_chapter_story_selection' ) ) {
);
}
}
+
+if ( ! function_exists( 'fictioneer_sql_get_story_chapter_relationship_data' ) ) {
+ /**
+ * Returns chapter objects for a story
+ *
+ * @since 5.26.0
+ *
+ * @global wpdb $wpdb WordPress database object.
+ *
+ * @param int $story_id Story ID.
+ *
+ * @return object[] Array of chapter data object similar to WP_Post.
+ */
+
+ function fictioneer_sql_get_story_chapter_relationship_data( $story_id ) {
+ global $wpdb;
+
+ // Setup
+ $chapter_ids = fictioneer_get_story_chapter_ids( $story_id );
+
+ // Empty?
+ if ( empty( $chapter_ids ) ) {
+ return [];
+ }
+
+ // Prepare SQL query
+ $placeholders = implode( ',', array_fill( 0, count( $chapter_ids ), '%d' ) );
+ $values = array_merge( $chapter_ids, [ $story_id ] );
+
+ $sql = $wpdb->prepare(
+ "SELECT p.ID as ID, p.post_title as post_title, p.post_status as post_status, p.post_date_gmt as post_date_gmt,
+ pm_text_icon.meta_value as fictioneer_chapter_text_icon,
+ pm_icon.meta_value as fictioneer_chapter_icon,
+ pm_rating.meta_value as fictioneer_chapter_rating,
+ pm_warning.meta_value as fictioneer_chapter_warning,
+ pm_group.meta_value as fictioneer_chapter_group,
+ pm_hidden.meta_value as fictioneer_chapter_hidden,
+ pm_no_chapter.meta_value as fictioneer_chapter_no_chapter
+ FROM {$wpdb->posts} p
+ LEFT JOIN {$wpdb->postmeta} pm_text_icon ON (p.ID = pm_text_icon.post_id AND pm_text_icon.meta_key = 'fictioneer_chapter_text_icon')
+ LEFT JOIN {$wpdb->postmeta} pm_icon ON (p.ID = pm_icon.post_id AND pm_icon.meta_key = 'fictioneer_chapter_icon')
+ LEFT JOIN {$wpdb->postmeta} pm_rating ON (p.ID = pm_rating.post_id AND pm_rating.meta_key = 'fictioneer_chapter_rating')
+ LEFT JOIN {$wpdb->postmeta} pm_warning ON (p.ID = pm_warning.post_id AND pm_warning.meta_key = 'fictioneer_chapter_warning')
+ LEFT JOIN {$wpdb->postmeta} pm_group ON (p.ID = pm_group.post_id AND pm_group.meta_key = 'fictioneer_chapter_group')
+ LEFT JOIN {$wpdb->postmeta} pm_hidden ON (p.ID = pm_hidden.post_id AND pm_hidden.meta_key = 'fictioneer_chapter_hidden')
+ LEFT JOIN {$wpdb->postmeta} pm_no_chapter ON (p.ID = pm_no_chapter.post_id AND pm_no_chapter.meta_key = 'fictioneer_chapter_no_chapter')
+ WHERE p.post_type = 'fcn_chapter'
+ AND p.ID IN ($placeholders)
+ AND EXISTS (
+ SELECT 1
+ FROM {$wpdb->postmeta} pm
+ WHERE pm.post_id = p.ID AND pm.meta_key = 'fictioneer_chapter_story' AND pm.meta_value = %d
+ )
+ ",
+ ...$values
+ );
+
+ // Execute
+ $results = $wpdb->get_results( $sql );
+
+ // Restore order and return
+ $chapter_map = array_flip( $chapter_ids );
+
+ usort( $results, function( $a, $b ) use ( $chapter_map ) {
+ return $chapter_map[ $a->ID ] <=> $chapter_map[ $b->ID ];
+ });
+
+ return $results;
+ }
+}
diff --git a/includes/functions/_setup-meta-fields.php b/includes/functions/_setup-meta-fields.php
index cfa8a453..385249c3 100644
--- a/includes/functions/_setup-meta-fields.php
+++ b/includes/functions/_setup-meta-fields.php
@@ -1128,6 +1128,7 @@ add_action( 'wp_ajax_fictioneer_ajax_query_relationship_posts', 'fictioneer_ajax
* Render HTML for selected story chapters
*
* @since 5.8.0
+ * @since 5.26.0 - Use custom chapter objects.
*
* @param array $selected Currently selected chapters.
* @param string $meta_key The meta key.
@@ -1137,11 +1138,15 @@ add_action( 'wp_ajax_fictioneer_ajax_query_relationship_posts', 'fictioneer_ajax
function fictioneer_callback_relationship_chapters( $selected, $meta_key, $args = [] ) {
// Build HTML
foreach ( $selected as $chapter ) {
- $title = fictioneer_get_safe_title( $chapter, 'admin-callback-relationship-chapters' );
+ $title = fictioneer_sanitize_safe_title(
+ $chapter->post_title,
+ get_date_from_gmt( $chapter->post_date_gmt, get_option( 'date_format' ) ),
+ get_date_from_gmt( $chapter->post_date_gmt, get_option( 'time_format' ) )
+ );
$classes = ['fictioneer-meta-field__relationships-item', 'fictioneer-meta-field__relationships-values-item'];
$label = fictioneer_get_post_status_label( $chapter->post_status );
- if ( get_post_meta( $chapter->ID, 'fictioneer_chapter_hidden', true ) ) {
+ if ( $chapter->fictioneer_chapter_hidden ) {
$title = "{$title} (" . _x( 'Unlisted', 'Chapter assignment flag.', 'fictioneer' ) . ")";
}
@@ -1274,29 +1279,31 @@ function fictioneer_ajax_get_relationship_chapters( $post_id, $meta_key ) {
*
* @since 5.8.0
*
- * @param WP_Post $chapter The chapter post.
+ * @param WP_Post|object $chapter The chapter post or similar object.
*
* @return string HTML for the chapter info.
*/
function fictioneer_get_relationship_chapter_details( $chapter ) {
// Setup
- $text_icon = get_post_meta( $chapter->ID, 'fictioneer_chapter_text_icon', true );
- $icon = fictioneer_get_icon_field( 'fictioneer_chapter_icon', $chapter->ID );
- $rating = get_post_meta( $chapter->ID, 'fictioneer_chapter_rating', true );
- $warning = get_post_meta( $chapter->ID, 'fictioneer_chapter_warning', true );
- $group = get_post_meta( $chapter->ID, 'fictioneer_chapter_group', true );
+ $text_icon = $chapter->fictioneer_chapter_text_icon ?? '';
+ $icon = fictioneer_get_icon_field( 'fictioneer_chapter_icon', null, $chapter->fictioneer_chapter_icon ?? '' );
+ $rating = $chapter->fictioneer_chapter_rating ?? '';
+ $warning = $chapter->fictioneer_chapter_warning ?? '';
+ $group = $chapter->fictioneer_chapter_group ?? '';
+ $date_local = get_date_from_gmt( $chapter->post_date_gmt, get_option( 'date_format' ) );
+ $time_local = get_date_from_gmt( $chapter->post_date_gmt, get_option( 'time_format' ) );
$flags = [];
$info = [];
// Build
$info[] = empty( $text_icon ) ? sprintf( '', $icon ) : "{$text_icon}";
- if ( get_post_meta( $chapter->ID, 'fictioneer_chapter_hidden', true ) ) {
+ if ( $chapter->fictioneer_chapter_hidden ?? 0 ) {
$flags[] = _x( 'Unlisted', 'Chapter assignment flag.', 'fictioneer' );
}
- if ( get_post_meta( $chapter->ID, 'fictioneer_chapter_no_chapter', true ) ) {
+ if ( $chapter->fictioneer_chapter_no_chapter ?? 0 ) {
$flags[] = _x( 'No Chapter', 'Chapter assignment flag.', 'fictioneer' );
}
@@ -1307,8 +1314,8 @@ function fictioneer_get_relationship_chapter_details( $chapter ) {
$info[] = sprintf(
_x( 'Date: %1$s at %2$s', 'Chapter assignment info.', 'fictioneer' ),
- get_the_date( '', $chapter->ID ),
- get_the_time( '', $chapter->ID )
+ $date_local,
+ $time_local
);
if ( ! empty( $group ) ) {
@@ -2044,23 +2051,6 @@ function fictioneer_render_story_data_metabox( $post ) {
);
// Chapters
- $chapter_ids = fictioneer_get_story_chapter_ids( $post->ID );
-
- $chapters = empty( $chapter_ids ) ? [] : get_posts(
- array(
- 'post_type' => 'fcn_chapter',
- 'post_status' => 'any',
- 'post__in' => $chapter_ids ?: [0], // Must not be empty!
- 'orderby' => 'post__in',
- 'posts_per_page' => -1,
- 'meta_key' => 'fictioneer_chapter_story',
- 'meta_value' => $post->ID,
- 'update_post_meta_cache' => true,
- 'update_post_term_cache' => false, // Improve performance
- 'no_found_rows' => true // Improve performance
- )
- );
-
$description = get_option( 'fictioneer_limit_chapter_stories_by_author' ) ?
__( 'Select and order chapters assigned to the story (set in the chapter). The author (or co-author) of the chapter and the story must match.', 'fictioneer' ) :
__( 'Select and order chapters assigned to the story (set in the chapter).', 'fictioneer' );
@@ -2068,7 +2058,7 @@ function fictioneer_render_story_data_metabox( $post ) {
$output['fictioneer_story_chapters'] = fictioneer_get_metabox_relationships(
$post,
'fictioneer_story_chapters',
- $chapters,
+ fictioneer_sql_get_story_chapter_relationship_data( $post->ID ),
'fictioneer_callback_relationship_chapters',
array(
'label' => _x( 'Chapters', 'Story chapters meta field label.', 'fictioneer' ),