wp/wp-includes/blocks/latest-posts.php
changeset 16 a86126ab1dd4
parent 9 177826044cd9
child 18 be944660c56a
--- a/wp/wp-includes/blocks/latest-posts.php	Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/blocks/latest-posts.php	Tue Dec 15 13:49:49 2020 +0100
@@ -6,6 +6,26 @@
  */
 
 /**
+ * The excerpt length set by the Latest Posts core block
+ * set at render time and used by the block itself.
+ *
+ * @var int
+ */
+$block_core_latest_posts_excerpt_length = 0;
+
+/**
+ * Callback for the excerpt_length filter used by
+ * the Latest Posts block at render time.
+ *
+ * @return int Returns the global $block_core_latest_posts_excerpt_length variable
+ *             to allow the excerpt_length filter respect the Latest Block setting.
+ */
+function block_core_latest_posts_get_excerpt_length() {
+	global $block_core_latest_posts_excerpt_length;
+	return $block_core_latest_posts_excerpt_length;
+}
+
+/**
  * Renders the `core/latest-posts` block on server.
  *
  * @param array $attributes The block attributes.
@@ -13,6 +33,8 @@
  * @return string Returns the post content with latest posts added.
  */
 function render_block_core_latest_posts( $attributes ) {
+	global $post, $block_core_latest_posts_excerpt_length;
+
 	$args = array(
 		'posts_per_page'   => $attributes['postsToShow'],
 		'post_status'      => 'publish',
@@ -21,8 +43,14 @@
 		'suppress_filters' => false,
 	);
 
+	$block_core_latest_posts_excerpt_length = $attributes['excerptLength'];
+	add_filter( 'excerpt_length', 'block_core_latest_posts_get_excerpt_length', 20 );
+
 	if ( isset( $attributes['categories'] ) ) {
-		$args['category'] = $attributes['categories'];
+		$args['category__in'] = array_column( $attributes['categories'], 'id' );
+	}
+	if ( isset( $attributes['selectedAuthor'] ) ) {
+		$args['author'] = $attributes['selectedAuthor'];
 	}
 
 	$recent_posts = get_posts( $args );
@@ -30,16 +58,60 @@
 	$list_items_markup = '';
 
 	foreach ( $recent_posts as $post ) {
+
+		$list_items_markup .= '<li>';
+
+		if ( $attributes['displayFeaturedImage'] && has_post_thumbnail( $post ) ) {
+			$image_style = '';
+			if ( isset( $attributes['featuredImageSizeWidth'] ) ) {
+				$image_style .= sprintf( 'max-width:%spx;', $attributes['featuredImageSizeWidth'] );
+			}
+			if ( isset( $attributes['featuredImageSizeHeight'] ) ) {
+				$image_style .= sprintf( 'max-height:%spx;', $attributes['featuredImageSizeHeight'] );
+			}
+
+			$image_classes = 'wp-block-latest-posts__featured-image';
+			if ( isset( $attributes['featuredImageAlign'] ) ) {
+				$image_classes .= ' align' . $attributes['featuredImageAlign'];
+			}
+
+			$list_items_markup .= sprintf(
+				'<div class="%1$s">%2$s</div>',
+				$image_classes,
+				get_the_post_thumbnail(
+					$post,
+					$attributes['featuredImageSizeSlug'],
+					array(
+						'style' => $image_style,
+					)
+				)
+			);
+		}
+
 		$title = get_the_title( $post );
 		if ( ! $title ) {
-			$title = __( '(Untitled)' );
+			$title = __( '(no title)' );
 		}
 		$list_items_markup .= sprintf(
-			'<li><a href="%1$s">%2$s</a>',
+			'<a href="%1$s">%2$s</a>',
 			esc_url( get_permalink( $post ) ),
 			$title
 		);
 
+		if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) {
+			$author_display_name = get_the_author_meta( 'display_name', $post->post_author );
+
+			/* translators: byline. %s: current author. */
+			$byline = sprintf( __( 'by %s' ), $author_display_name );
+
+			if ( ! empty( $author_display_name ) ) {
+				$list_items_markup .= sprintf(
+					'<div class="wp-block-latest-posts__post-author">%1$s</div>',
+					esc_html( $byline )
+				);
+			}
+		}
+
 		if ( isset( $attributes['displayPostDate'] ) && $attributes['displayPostDate'] ) {
 			$list_items_markup .= sprintf(
 				'<time datetime="%1$s" class="wp-block-latest-posts__post-date">%2$s</time>',
@@ -48,10 +120,31 @@
 			);
 		}
 
+		if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
+			&& isset( $attributes['displayPostContentRadio'] ) && 'excerpt' === $attributes['displayPostContentRadio'] ) {
+
+			$trimmed_excerpt = get_the_excerpt( $post );
+
+			$list_items_markup .= sprintf(
+				'<div class="wp-block-latest-posts__post-excerpt">%1$s</div>',
+				$trimmed_excerpt
+			);
+		}
+
+		if ( isset( $attributes['displayPostContent'] ) && $attributes['displayPostContent']
+			&& isset( $attributes['displayPostContentRadio'] ) && 'full_post' === $attributes['displayPostContentRadio'] ) {
+			$list_items_markup .= sprintf(
+				'<div class="wp-block-latest-posts__post-full-content">%1$s</div>',
+				wp_kses_post( html_entity_decode( $post->post_content, ENT_QUOTES, get_option( 'blog_charset' ) ) )
+			);
+		}
+
 		$list_items_markup .= "</li>\n";
 	}
 
-	$class = 'wp-block-latest-posts';
+	remove_filter( 'excerpt_length', 'block_core_latest_posts_get_excerpt_length', 20 );
+
+	$class = 'wp-block-latest-posts wp-block-latest-posts__list';
 	if ( isset( $attributes['align'] ) ) {
 		$class .= ' align' . $attributes['align'];
 	}
@@ -68,64 +161,61 @@
 		$class .= ' has-dates';
 	}
 
+	if ( isset( $attributes['displayAuthor'] ) && $attributes['displayAuthor'] ) {
+		$class .= ' has-author';
+	}
+
 	if ( isset( $attributes['className'] ) ) {
 		$class .= ' ' . $attributes['className'];
 	}
 
-	$block_content = sprintf(
+	return sprintf(
 		'<ul class="%1$s">%2$s</ul>',
 		esc_attr( $class ),
 		$list_items_markup
 	);
-
-	return $block_content;
 }
 
 /**
  * Registers the `core/latest-posts` block on server.
  */
 function register_block_core_latest_posts() {
-	register_block_type(
-		'core/latest-posts',
+	register_block_type_from_metadata(
+		__DIR__ . '/latest-posts',
 		array(
-			'attributes'      => array(
-				'categories'      => array(
-					'type' => 'string',
-				),
-				'className'       => array(
-					'type' => 'string',
-				),
-				'postsToShow'     => array(
-					'type'    => 'number',
-					'default' => 5,
-				),
-				'displayPostDate' => array(
-					'type'    => 'boolean',
-					'default' => false,
-				),
-				'postLayout'      => array(
-					'type'    => 'string',
-					'default' => 'list',
-				),
-				'columns'         => array(
-					'type'    => 'number',
-					'default' => 3,
-				),
-				'align'           => array(
-					'type' => 'string',
-				),
-				'order'           => array(
-					'type'    => 'string',
-					'default' => 'desc',
-				),
-				'orderBy'         => array(
-					'type'    => 'string',
-					'default' => 'date',
-				),
-			),
 			'render_callback' => 'render_block_core_latest_posts',
 		)
 	);
 }
+add_action( 'init', 'register_block_core_latest_posts' );
 
-add_action( 'init', 'register_block_core_latest_posts' );
+/**
+ * Handles outdated versions of the `core/latest-posts` block by converting
+ * attribute `categories` from a numeric string to an array with key `id`.
+ *
+ * This is done to accommodate the changes introduced in #20781 that sought to
+ * add support for multiple categories to the block. However, given that this
+ * block is dynamic, the usual provisions for block migration are insufficient,
+ * as they only act when a block is loaded in the editor.
+ *
+ * TODO: Remove when and if the bottom client-side deprecation for this block
+ * is removed.
+ *
+ * @param array $block A single parsed block object.
+ *
+ * @return array The migrated block object.
+ */
+function block_core_latest_posts_migrate_categories( $block ) {
+	if (
+		'core/latest-posts' === $block['blockName'] &&
+		! empty( $block['attrs']['categories'] ) &&
+		is_string( $block['attrs']['categories'] )
+	) {
+		$block['attrs']['categories'] = array(
+			array( 'id' => absint( $block['attrs']['categories'] ) ),
+		);
+	}
+
+	return $block;
+}
+add_filter( 'render_block_data', 'block_core_latest_posts_migrate_categories' );