1<?php
2/**
3 * Server-side rendering of the `core/post-date` block.
4 *
5 * @package WordPress
6 */
7
8/**
9 * Renders the `core/post-date` block on the server.
10 *
11 * @since 5.8.0
12 * @since 6.9.0 Added `datetime` attribute and Block Bindings support.
13 *
14 * @param array $attributes Block attributes.
15 * @param string $content Block default content.
16 * @param WP_Block $block Block instance.
17 * @return string Returns the filtered post date for the current post wrapped inside "time" tags.
18 */
19function render_block_core_post_date( $attributes, $content, $block ) {
20 $classes = array();
21
22 if (
23 ! isset( $attributes['datetime'] ) && ! (
24 isset( $attributes['metadata']['bindings']['datetime']['source'] ) &&
25 isset( $attributes['metadata']['bindings']['datetime']['args'] )
26 )
27 ) {
28 /*
29 * This is the legacy version of the block that didn't have the `datetime` attribute.
30 * This branch needs to be kept for backward compatibility.
31 */
32 $source = get_block_bindings_source( 'core/post-data' );
33 if ( isset( $attributes['displayType'] ) && 'modified' === $attributes['displayType'] ) {
34 $source_args = array(
35 'field' => 'modified',
36 );
37 } else {
38 $source_args = array(
39 'field' => 'date',
40 );
41 }
42 $attributes['datetime'] = $source->get_value( $source_args, $block, 'datetime' );
43 }
44
45 if ( isset( $source_args['field'] ) && 'modified' === $source_args['field'] ) {
46 $classes[] = 'wp-block-post-date__modified-date';
47 }
48
49 if ( empty( $attributes['datetime'] ) ) {
50 // If the `datetime` attribute is set but empty, it could be because Block Bindings
51 // set it that way. This can happen e.g. if the block is bound to the
52 // post's last modified date, and the latter lies before the publish date.
53 // (See https://github.com/WordPress/gutenberg/pull/46839 where this logic was originally
54 // implemented.)
55 // In this case, we have to respect and return the empty value.
56 return '';
57 }
58
59 $unformatted_date = $attributes['datetime'];
60 $post_timestamp = strtotime( $unformatted_date );
61
62 if ( isset( $attributes['format'] ) && 'human-diff' === $attributes['format'] ) {
63 if ( $post_timestamp > time() ) {
64 // translators: %s: human-readable time difference.
65 $formatted_date = sprintf( __( '%s from now' ), human_time_diff( $post_timestamp ) );
66 } else {
67 // translators: %s: human-readable time difference.
68 $formatted_date = sprintf( __( '%s ago' ), human_time_diff( $post_timestamp ) );
69 }
70 } else {
71 $format = empty( $attributes['format'] ) ? get_option( 'date_format' ) : $attributes['format'];
72 $formatted_date = wp_date( $format, $post_timestamp );
73 }
74
75 if ( isset( $attributes['textAlign'] ) ) {
76 $classes[] = 'has-text-align-' . $attributes['textAlign'];
77 }
78 if ( isset( $attributes['style']['elements']['link']['color']['text'] ) ) {
79 $classes[] = 'has-link-color';
80 }
81
82 $wrapper_attributes = get_block_wrapper_attributes( array( 'class' => implode( ' ', $classes ) ) );
83
84 if ( isset( $attributes['isLink'] ) && $attributes['isLink'] && isset( $block->context['postId'] ) ) {
85 $formatted_date = sprintf( '<a href="%1s">%2s</a>', get_the_permalink( $block->context['postId'] ), $formatted_date );
86 }
87
88 return sprintf(
89 '<div %1$s><time datetime="%2$s">%3$s</time></div>',
90 $wrapper_attributes,
91 $unformatted_date,
92 $formatted_date
93 );
94}
95
96/**
97 * Registers the `core/post-date` block on the server.
98 *
99 * @since 5.8.0
100 */
101function register_block_core_post_date() {
102 register_block_type_from_metadata(
103 __DIR__ . '/post-date',
104 array(
105 'render_callback' => 'render_block_core_post_date',
106 )
107 );
108}
109add_action( 'init', 'register_block_core_post_date' );
110