| @@ -43,9 +43,8 @@ | ||
| 43 | 43 | * @return string Returns the post content with latest posts added. |
| 44 | 44 | */ |
| 45 | 45 | function gutenberg_render_block_core_latest_posts( $attributes ) { |
| 46 | 46 | global $post, $block_core_latest_posts_excerpt_length; |
| 47 | - static $rendering_stack = array(); | |
| 48 | 47 | |
| 49 | 48 | $args = array( |
| 50 | 49 | 'posts_per_page' => $attributes['postsToShow'], |
| 51 | 50 | 'post_status' => 'publish', |
| @@ -64,9 +63,10 @@ | ||
| 64 | 63 | if ( isset( $attributes['selectedAuthor'] ) ) { |
| 65 | 64 | $args['author'] = $attributes['selectedAuthor']; |
| 66 | 65 | } |
| 67 | 66 | |
| 68 | - $query = new WP_Query( $args ); | |
| 67 | + $query = new WP_Query(); | |
| 68 | + $recent_posts = $query->query( $args ); | |
| 69 | 69 | |
| 70 | 70 | if ( isset( $attributes['displayFeaturedImage'] ) && $attributes['displayFeaturedImage'] ) { |
| 71 | 71 | update_post_thumbnail_cache( $query ); |
| 72 | 72 | } |
| @@ -71,18 +71,12 @@ | ||
| 71 | 71 | update_post_thumbnail_cache( $query ); |
| 72 | 72 | } |
| 73 | 73 | |
| 74 | 74 | $list_items_markup = ''; |
| 75 | - // Snapshot the current global post so it can be restored after the loop. | |
| 76 | - // We use have_posts()/the_post() rather than foreach so that setup_postdata() | |
| 77 | - // is called for each post, establishing the correct global context for | |
| 78 | - // do_blocks() and other filters that run during full-content rendering. | |
| 79 | - $previous_post = $post ?? null; | |
| 80 | 75 | |
| 81 | - while ( $query->have_posts() ) { | |
| 82 | - $query->the_post(); | |
| 83 | - $post_link = esc_url( get_permalink() ); | |
| 84 | - $title = get_the_title(); | |
| 76 | + foreach ( $recent_posts as $post ) { | |
| 77 | + $post_link = esc_url( get_permalink( $post ) ); | |
| 78 | + $title = get_the_title( $post ); | |
| 85 | 79 | |
| 86 | 80 | if ( ! $title ) { |
| 87 | 81 | $title = __( '(no title)' ); |
| 88 | 82 | } |
| @@ -88,9 +82,9 @@ | ||
| 88 | 82 | } |
| 89 | 83 | |
| 90 | 84 | $list_items_markup .= '<li>'; |
| 91 | 85 | |
| 92 | - if ( $attributes['displayFeaturedImage'] && has_post_thumbnail() ) { | |
| 86 | + if ( $attributes['displayFeaturedImage'] && has_post_thumbnail( $post ) ) { | |
| 93 | 87 | $image_style = ''; |
| 94 | 88 | if ( isset( $attributes['featuredImageSizeWidth'] ) ) { |
| 95 | 89 | $image_style .= sprintf( 'max-width:%spx;', $attributes['featuredImageSizeWidth'] ); |
| 96 | 90 | } |
| @@ -103,9 +97,9 @@ | ||
| 103 | 97 | $image_classes .= ' align' . $attributes['featuredImageAlign']; |
| 104 | 98 | } |
| 105 | 99 | |
| 106 | 100 | $featured_image = get_the_post_thumbnail( |
| 107 | - null, | |
| 101 | + $post, | |
| 108 | 102 | $attributes['featuredImageSizeSlug'], |
| 109 | 103 | array( |
| 110 | 104 | 'style' => esc_attr( $image_style ), |
| 111 | 105 | ) |
| @@ -131,9 +125,9 @@ | ||
| 131 | 125 | $title |
| 132 | 126 | ); |
| 133 | 127 | |
| 134 | 128 | if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) { |
| 135 | - $author_display_name = get_the_author_meta( 'display_name' ); | |
| 129 | + $author_display_name = get_the_author_meta( 'display_name', $post->post_author ); | |
| 136 | 130 | |
| 137 | 131 | /* translators: byline. %s: author. */ |
| 138 | 132 | $byline = sprintf( __( 'by %s' ), $author_display_name ); |
| 139 | 133 | |
| @@ -147,10 +141,10 @@ | ||
| 147 | 141 | |
| 148 | 142 | if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) { |
| 149 | 143 | $list_items_markup .= sprintf( |
| 150 | 144 | '<time datetime="%1$s" class="wp-block-latest-posts__post-date">%2$s</time>', |
| 151 | - esc_attr( get_the_date( 'c' ) ), | |
| 152 | - get_the_date( '' ) | |
| 145 | + esc_attr( get_the_date( 'c', $post ) ), | |
| 146 | + get_the_date( '', $post ) | |
| 153 | 147 | ); |
| 154 | 148 | } |
| 155 | 149 | |
| 156 | 150 | if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent'] |
| @@ -155,9 +149,9 @@ | ||
| 155 | 149 | |
| 156 | 150 | if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent'] |
| 157 | 151 | && isset( $attributes['displayPostContentRadio'] ) && 'excerpt' === $attributes['displayPostContentRadio'] ) { |
| 158 | 152 | |
| 159 | - $trimmed_excerpt = get_the_excerpt(); | |
| 153 | + $trimmed_excerpt = get_the_excerpt( $post ); | |
| 160 | 154 | |
| 161 | 155 | /* |
| 162 | 156 | * Adds a "Read more" link with screen reader text. |
| 163 | 157 | * […] is the default excerpt ending from wp_trim_excerpt() in Core. |
| @@ -168,9 +162,9 @@ | ||
| 168 | 162 | if ( $excerpt_length <= $block_core_latest_posts_excerpt_length ) { |
| 169 | 163 | $trimmed_excerpt = substr( $trimmed_excerpt, 0, -11 ); |
| 170 | 164 | $trimmed_excerpt .= sprintf( |
| 171 | 165 | /* translators: 1: A URL to a post, 2: Hidden accessibility text: Post title */ |
| 172 | - __( '… <a class="wp-block-latest-posts__read-more" href="%1$s" rel="noopener">Read more<span class="screen-reader-text">: %2$s</span></a>' ), | |
| 166 | + __( '… <a class="wp-block-latest-posts__read-more" href="%1$s" rel="noopener noreferrer">Read more<span class="screen-reader-text">: %2$s</span></a>' ), | |
| 173 | 167 | esc_url( $post_link ), |
| 174 | 168 | esc_html( $title ) |
| 175 | 169 | ); |
| 176 | 170 | } |
| @@ -175,9 +169,9 @@ | ||
| 175 | 169 | ); |
| 176 | 170 | } |
| 177 | 171 | } |
| 178 | 172 | |
| 179 | - if ( post_password_required() ) { | |
| 173 | + if ( post_password_required( $post ) ) { | |
| 180 | 174 | $trimmed_excerpt = __( 'This content is password protected.' ); |
| 181 | 175 | } |
| 182 | 176 | |
| 183 | 177 | $list_items_markup .= sprintf( |
| @@ -188,32 +182,17 @@ | ||
| 188 | 182 | |
| 189 | 183 | if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent'] |
| 190 | 184 | && isset( $attributes['displayPostContentRadio'] ) && 'full_post' === $attributes['displayPostContentRadio'] ) { |
| 191 | 185 | |
| 192 | - if ( post_password_required() ) { | |
| 186 | + $post_content = html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) ); | |
| 187 | + | |
| 188 | + if ( post_password_required( $post ) ) { | |
| 193 | 189 | $post_content = __( 'This content is password protected.' ); |
| 194 | - } else { | |
| 195 | - $post_id = get_the_ID(); | |
| 196 | - $post_content = get_post_field( 'post_content', $post_id, 'raw' ); | |
| 197 | - // Check if we're already rendering this post to prevent infinite recursion. | |
| 198 | - if ( in_array( $post_id, $rendering_stack, true ) ) { | |
| 199 | - $post_content = ''; | |
| 200 | - } else { | |
| 201 | - $rendering_stack[] = $post_id; | |
| 202 | - | |
| 203 | - try { | |
| 204 | - // Run through the actions that are typically taken on the_content. | |
| 205 | - $post_content = _wp_apply_block_content_filters( $post_content, 'latest-posts' ); | |
| 206 | - } finally { | |
| 207 | - array_pop( $rendering_stack ); | |
| 208 | - } | |
| 209 | - } | |
| 210 | 190 | } |
| 211 | 191 | |
| 212 | - $post_content = str_replace( ']]>', ']]>', $post_content ); | |
| 213 | 192 | $list_items_markup .= sprintf( |
| 214 | 193 | '<div class="wp-block-latest-posts__post-full-content">%1$s</div>', |
| 215 | - $post_content | |
| 194 | + wp_kses_post( $post_content ) | |
| 216 | 195 | ); |
| 217 | 196 | } |
| 218 | 197 | |
| 219 | 198 | $list_items_markup .= "</li>\n"; |
| @@ -218,36 +197,16 @@ | ||
| 218 | 197 | |
| 219 | 198 | $list_items_markup .= "</li>\n"; |
| 220 | 199 | } |
| 221 | 200 | |
| 222 | - // Restore the post context that was active before this secondary query. | |
| 223 | - // wp_reset_postdata() is intentionally not used here: when this block is | |
| 224 | - // rendered inside another post's content (e.g. via do_blocks()), it would | |
| 225 | - // restore to the main query post rather than the outer rendering post. | |
| 226 | - $post = $previous_post; | |
| 227 | - if ( $previous_post instanceof WP_Post ) { | |
| 228 | - setup_postdata( $previous_post ); | |
| 229 | - } | |
| 230 | - | |
| 231 | 201 | remove_filter( 'excerpt_length', 'gutenberg_block_core_latest_posts_get_excerpt_length', 20 ); |
| 232 | 202 | |
| 233 | - $layout = $attributes['layout'] ?? array(); | |
| 234 | - $legacy_layout_type = ( | |
| 235 | - isset( $attributes['postLayout'] ) && | |
| 236 | - 'grid' === $attributes['postLayout'] | |
| 237 | - ) ? 'grid' : 'default'; | |
| 238 | - $layout_type = $layout['type'] ?? $legacy_layout_type; | |
| 239 | - $column_count = $layout['columnCount'] ?? ( $attributes['columns'] ?? null ); | |
| 240 | - | |
| 241 | 203 | $classes = array( 'wp-block-latest-posts__list' ); |
| 242 | - if ( 'grid' === $layout_type ) { | |
| 204 | + if ( isset( $attributes['postLayout'] ) && 'grid' === $attributes['postLayout'] ) { | |
| 243 | 205 | $classes[] = 'is-grid'; |
| 244 | 206 | } |
| 245 | - if ( 'grid' === $layout_type && ! empty( $column_count ) ) { | |
| 246 | - $classes[] = sanitize_title( 'columns-' . $column_count ); | |
| 247 | - } | |
| 248 | - if ( 'grid' === $layout_type && ! empty( $column_count ) && ! empty( $layout['minimumColumnWidth'] ) ) { | |
| 249 | - $classes[] = 'has-native-responsive-grid'; | |
| 207 | + if ( isset( $attributes['columns'] ) && 'grid' === $attributes['postLayout'] ) { | |
| 208 | + $classes[] = 'columns-' . $attributes['columns']; | |
| 250 | 209 | } |
| 251 | 210 | if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) { |
| 252 | 211 | $classes[] = 'has-dates'; |
| 253 | 212 | } |