From 624abe52205fc332c44a1c215f091d00ef31db72 Mon Sep 17 00:00:00 2001 From: Tetrakern <26898880+Tetrakern@users.noreply.github.com> Date: Sun, 27 Oct 2024 16:11:09 +0100 Subject: [PATCH] Use SQL to filter out invalid page IDs when story is saved --- includes/functions/_helpers-query.php | 64 +++++++++++++++++++++-- includes/functions/_setup-meta-fields.php | 27 ++-------- 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/includes/functions/_helpers-query.php b/includes/functions/_helpers-query.php index ee033ddd..25ff2b09 100644 --- a/includes/functions/_helpers-query.php +++ b/includes/functions/_helpers-query.php @@ -379,7 +379,7 @@ function fictioneer_set_chapter_story_parent( $chapter_id, $story_id ) { if ( ! function_exists( 'fictioneer_sql_filter_valid_chapter_ids' ) ) { /** - * Filters out non-valid chapters for ID array + * Filters out non-valid chapter array IDs * * Note: This is up to 3 times faster than using WP_Query. * @@ -411,7 +411,7 @@ if ( ! function_exists( 'fictioneer_sql_filter_valid_chapter_ids' ) ) { $placeholders = implode( ',', array_fill( 0, count( $chapter_ids ), '%d' ) ); $values = $chapter_ids; - // Prepare SQL + // Prepare SQL query $sql = "SELECT p.ID FROM {$wpdb->posts} p @@ -436,6 +436,64 @@ if ( ! function_exists( 'fictioneer_sql_filter_valid_chapter_ids' ) ) { } } +if ( ! function_exists( 'fictioneer_sql_filter_valid_page_ids' ) ) { + /** + * Filters out non-valid story page array IDs + * + * Note: This is up to 3 times faster than using WP_Query. + * + * @since 5.26.0 + * + * @global wpdb $wpdb WordPress database object. + * + * @param int $author_id Author ID for the pages. + * @param int[] $page_ids Array of page IDs. + * + * @return int[] Filtered array of page IDs. + */ + + function fictioneer_sql_filter_valid_page_ids( $author_id, $page_ids ) { + global $wpdb; + + // Prepare + $page_ids = is_array( $page_ids ) ? $page_ids : [ $page_ids ]; + $page_ids = array_map( 'intval', $page_ids ); + $page_ids = array_filter( $page_ids, function( $value ) { return $value > 0; } ); + + // Empty? + if ( empty( $page_ids ) || FICTIONEER_MAX_CUSTOM_PAGES_PER_STORY < 1 ) { + return []; + } + + // Prepare some more + $page_ids = array_unique( $page_ids ); + $page_ids = array_slice( $page_ids, 0, FICTIONEER_MAX_CUSTOM_PAGES_PER_STORY ); + + // Prepare placeholders + $placeholders = implode( ',', array_fill( 0, count( $page_ids ), '%d' ) ); + + // Prepare SQL query + $sql = + "SELECT p.ID + FROM {$wpdb->posts} p + WHERE p.post_type = 'page' + AND p.ID IN ($placeholders) + AND p.post_author = %d + LIMIT %d"; + + $query = $wpdb->prepare( + $sql, + ...array_merge( $page_ids, [ $author_id, FICTIONEER_MAX_CUSTOM_PAGES_PER_STORY ] ) + ); + + // Execute + $filtered_page_ids = $wpdb->get_col( $query ); + + // Restore order and return + return array_values( array_intersect( $page_ids, $filtered_page_ids ) ); + } +} + if ( ! function_exists( 'fictioneer_sql_has_new_story_chapters' ) ) { /** * Checks whether there any added chapters are to be considered "new". @@ -469,7 +527,7 @@ if ( ! function_exists( 'fictioneer_sql_has_new_story_chapters' ) ) { $chapter_placeholders = implode( ',', array_fill( 0, count( $chapter_diff ), '%d' ) ); $status_placeholders = implode( ',', array_fill( 0, count( $allowed_statuses ), '%s' ) ); - // Prepare SQL + // Prepare SQL query $sql = "SELECT p.ID FROM {$wpdb->posts} p diff --git a/includes/functions/_setup-meta-fields.php b/includes/functions/_setup-meta-fields.php index 2da636a5..b89faa7b 100644 --- a/includes/functions/_setup-meta-fields.php +++ b/includes/functions/_setup-meta-fields.php @@ -2382,32 +2382,13 @@ function fictioneer_save_story_metaboxes( $post_id ) { isset( $_POST['fictioneer_story_custom_pages'] ) && current_user_can( 'fcn_story_pages', $post_id ) ) { - $page_ids = $_POST['fictioneer_story_custom_pages']; - $page_ids = is_array( $page_ids ) ? $page_ids : [ $page_ids ]; - $page_ids = array_map( 'intval', $page_ids ); - $page_ids = array_filter( $page_ids, function( $value ) { return $value > 0; } ); + // Filter out non-valid page IDs + $page_ids = fictioneer_sql_filter_valid_page_ids( $post_author_id, $_POST['fictioneer_story_custom_pages'] ); - if ( empty( $page_ids ) || FICTIONEER_MAX_CUSTOM_PAGES_PER_STORY < 1 ) { + if ( empty( $page_ids ) ) { $fields['fictioneer_story_custom_pages'] = []; // Ensure empty meta is removed } else { - $page_ids = array_unique( $page_ids ); - $page_ids = array_slice( $page_ids, 0, FICTIONEER_MAX_CUSTOM_PAGES_PER_STORY ); - - $pages_query = new WP_Query( - array( - 'post_type' => 'page', - 'post__in' => $page_ids ?: [0], // Must not be empty! - 'author' => $post_author_id, // Only allow author's pages - 'orderby' => 'post__in', - 'fields' => 'ids', - 'posts_per_page' => FICTIONEER_MAX_CUSTOM_PAGES_PER_STORY, - 'update_post_meta_cache' => false, // Improve performance - 'update_post_term_cache' => false, // Improve performance - 'no_found_rows' => true // Improve performance - ) - ); - - $fields['fictioneer_story_custom_pages'] = array_map( 'strval', $pages_query->posts ); + $fields['fictioneer_story_custom_pages'] = array_map( 'strval', $page_ids ); } }