From d6ca9bd79b0d9e09ae69c421acf01415ecd9d7a1 Mon Sep 17 00:00:00 2001 From: Tetrakern <26898880+Tetrakern@users.noreply.github.com> Date: Tue, 5 Nov 2024 21:10:00 +0100 Subject: [PATCH] Use SQL to get chapter relationship metabox data --- includes/functions/_helpers-query.php | 70 +++++++++++++++++++++++ includes/functions/_setup-meta-fields.php | 50 +++++++--------- 2 files changed, 90 insertions(+), 30 deletions(-) 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' ),