Use SQL to build chapter story selection

And fix the status note as well.
This commit is contained in:
Tetrakern 2024-10-27 19:25:15 +01:00
parent 2d55285b8c
commit ff390364c9
2 changed files with 94 additions and 61 deletions

View File

@ -547,3 +547,93 @@ if ( ! function_exists( 'fictioneer_sql_has_new_story_chapters' ) ) {
return ! empty( $new_chapters );
}
}
if ( ! function_exists( 'fictioneer_sql_get_chapter_story_selection' ) ) {
/**
* Returns selectable stories for chapter assignments
*
* @since 5.26.0
*
* @global wpdb $wpdb WordPress database object.
*
* @param int $post_author_id Author ID of the current post.
* @param int $current_story_id ID of the currently selected story (if any).
*
* @return array Associative array with 'stories' (array) and 'other_author' (bool).
*/
function fictioneer_sql_get_chapter_story_selection( $post_author_id, $current_story_id = 0 ) {
global $wpdb;
// Setup
$stories = array( '0' => _x( '— Unassigned —', 'Chapter story select option.', 'fictioneer' ) );
$other_author = false;
// Prepare SQL query
$values = [];
$sql =
"SELECT p.ID, p.post_title, p.post_status, p.post_date, p.post_author
FROM {$wpdb->posts} p
WHERE p.post_type = 'fcn_story'
AND p.post_status IN ('publish', 'private')";
if ( get_option( 'fictioneer_limit_chapter_stories_by_author' ) ) {
$sql .= " AND p.post_author = %d";
$values[] = $post_author_id;
}
$sql .= " ORDER BY p.post_date DESC";
// Execute
$results = $wpdb->get_results( $wpdb->prepare( $sql, ...$values ) );
// Populate the stories array
foreach ( $results as $story ) {
$title = fictioneer_sanitize_safe_title(
$story->post_title,
mysql2date( get_option( 'date_format' ), $story->post_date ),
mysql2date( get_option( 'time_format' ), $story->post_date )
);
if ( $story->post_status !== 'publish' ) {
$stories[ $story->ID ] = sprintf(
_x( '%s (%s)', 'Chapter story meta field option with status label.', 'fictioneer' ),
$title,
fictioneer_get_post_status_label( $story->post_status )
);
} else {
$stories[ $story->ID ] = $title;
}
}
// Check for deviating assignment...
if ( $current_story_id && ! array_key_exists( $current_story_id, $stories ) ) {
$other_author_id = get_post_field( 'post_author', $current_story_id );
$suffix = [];
// Other author
if ( $other_author_id != $post_author_id ) {
$other_author = true;
$suffix['author'] = get_the_author_meta( 'display_name', $other_author_id );
}
// Other status
if ( get_post_status( $current_story_id ) !== 'publish' ) {
$suffix['status'] = fictioneer_get_post_status_label( get_post_status( $current_story_id ) );
}
// Append to selection
$stories[ $current_story_id ] = sprintf(
_x( '%s %s', 'Chapter story meta field mismatched option with author and/or status label.', 'fictioneer' ),
fictioneer_get_safe_title( $current_story_id, 'admin-render-chapter-data-metabox-current-suffix' ),
( ! empty( $suffix ) ? ' (' . implode( ' | ', $suffix ) . ')' : '' )
);
}
return array(
'stories' => $stories,
'other_author' => $other_author
);
}
}

View File

@ -2676,67 +2676,10 @@ function fictioneer_render_chapter_data_metabox( $post ) {
// --- Add fields ------------------------------------------------------------
// Story
$stories = array( '0' => _x( '— Unassigned —', 'Chapter story select option.', 'fictioneer' ) );
$description = __( 'Select the story this chapter belongs to; assign and order in the story.', 'fictioneer' );
$author_warning = '';
$selectable_stories_args = array(
'post_type' => 'fcn_story',
'post_status' => ['publish', 'private'],
'posts_per_page'=> -1,
'update_post_meta_cache' => false, // Improve performance
'update_post_term_cache' => false, // Improve performance
'no_found_rows' => true // Improve performance
);
$story_selection = fictioneer_sql_get_chapter_story_selection( $post_author_id, $current_story_id );
$stories = $story_selection['stories'];
if ( get_option( 'fictioneer_limit_chapter_stories_by_author' ) ) {
$selectable_stories_args['author'] = $post_author_id;
}
$selectable_stories = new WP_Query( $selectable_stories_args );
if ( $selectable_stories->have_posts() ) {
foreach ( $selectable_stories->posts as $story ) {
if ( $story->post_status !== 'publish' ) {
$stories[ $story->ID ] = sprintf(
_x( '%s (%s)', 'Chapter story meta field option with status label.', 'fictioneer' ),
fictioneer_get_safe_title( $story->ID, 'admin-render-chapter-data-metabox-selectable-suffix' ),
fictioneer_get_post_status_label( $story->post_status )
);
} else {
$stories[ $story->ID ] = fictioneer_get_safe_title( $story->ID, 'admin-render-chapter-data-metabox-selectable' );
}
}
}
if ( $current_story_id ) {
// Check unmatched story assignment...
if ( ! array_key_exists( $current_story_id, $stories ) ) {
$other_author_id = get_post_field( 'post_author', $current_story_id );
$suffix = [];
// Other author
if ( $other_author_id != $post_author_id ) {
$suffix['author'] = get_the_author_meta( 'display_name', $other_author_id );
$author_warning = __( '<strong>Warning:</strong> The selected story belongs to another author. If you change the selection, you cannot go back.', 'fictioneer' );
}
// Other status
if ( get_post_status( $current_story_id ) === 'publish' ) {
$suffix['status'] = fictioneer_get_post_status_label( $story->post_status );
}
// Prepare suffix
if ( ! empty( $suffix ) ) {
$suffix = ' (' . implode( ' | ', $suffix ) . ')';
}
$stories[ $current_story_id ] = sprintf(
_x( '%s %s', 'Chapter story meta field mismatched option with author and/or status label.', 'fictioneer' ),
fictioneer_get_safe_title( $current_story_id, 'admin-render-chapter-data-metabox-current-suffix' ),
$suffix
);
}
}
$author_warning = $story_selection['other_author'] ? ' ' . __( '<strong>Warning:</strong> The selected story belongs to another author. If you change the selection, you cannot go back.', 'fictioneer' ) : '';
if ( get_option( 'fictioneer_enable_chapter_appending' ) ) {
$description = __( 'Select the story this chapter belongs to. Published and scheduled chapters are automatically appended to the story.', 'fictioneer' );
@ -2748,7 +2691,7 @@ function fictioneer_render_chapter_data_metabox( $post ) {
$stories,
array(
'label' => _x( 'Story', 'Chapter story meta field label.', 'fictioneer' ),
'description' => $description . ' ' . $author_warning,
'description' => $description . $author_warning,
'attributes' => array(
'data-action="select-story"',
"data-target='chapter_groups_for_{$post->ID}'"