Completed
Push — add/homepage-articles ( 7bb8ee )
by
unknown
58:57 queued 50:32
created

homepage-articles.php ➔ newspack_blocks_format_byline()   A

Complexity

Conditions 5
Paths 1

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
nc 1
nop 1
dl 0
loc 37
rs 9.0168
c 0
b 0
f 0
1
<?php
2
/**
3
 * Homepage Articles.
4
 * Server-side rendering of the `jetpack/homepage-posts` block.
5
 *
6
 * @package Jetpack
7
 */
8
9
namespace Automattic\Jetpack\Extensions\HomepageArticles;
10
11
require_once 'newspack-blocks.php';
12
13
/**
14
 * Renders the `jetpack/homepage-posts` block on server.
15
 *
16
 * @param array $attributes The block attributes.
17
 *
18
 * @return string Returns the post content with latest posts added.
19
 */
20
function newspack_blocks_render_block_homepage_articles( $attributes ) {
21
	// Don't output the block inside RSS feeds.
22
	if ( is_feed() ) {
23
		return;
24
	}
25
26
	// This will let the FSE plugin know we need CSS/JS now.
27
	do_action( 'newspack_blocks_render_homepage_articles' );
28
29
	$article_query = new \WP_Query( \Newspack_Blocks::build_articles_query( $attributes ) );
30
31
	$classes = \Newspack_Blocks::block_classes( 'homepage-articles', $attributes, array( 'wpnbha' ) );
32
33
	if ( isset( $attributes['postLayout'] ) && 'grid' === $attributes['postLayout'] ) {
34
		$classes .= ' is-grid';
35
	}
36
	if ( isset( $attributes['columns'] ) && 'grid' === $attributes['postLayout'] ) {
37
		$classes .= ' columns-' . $attributes['columns'];
38
	}
39
	if ( $attributes['showImage'] ) {
40
		$classes .= ' show-image';
41
	}
42 View Code Duplication
	if ( $attributes['showImage'] && isset( $attributes['mediaPosition'] ) ) {
43
		$classes .= ' image-align' . $attributes['mediaPosition'];
44
	}
45
	if ( isset( $attributes['typeScale'] ) ) {
46
		$classes .= ' ts-' . $attributes['typeScale'];
47
	}
48 View Code Duplication
	if ( $attributes['showImage'] && isset( $attributes['imageScale'] ) ) {
49
		$classes .= ' is-' . $attributes['imageScale'];
50
	}
51
	if ( $attributes['showImage'] ) {
52
		$classes .= ' is-' . $attributes['imageShape'];
53
	}
54
	if ( $attributes['showImage'] && $attributes['mobileStack'] ) {
55
		$classes .= ' mobile-stack';
56
	}
57
	if ( $attributes['showCaption'] ) {
58
		$classes .= ' show-caption';
59
	}
60
	if ( $attributes['showCategory'] ) {
61
		$classes .= ' show-category';
62
	}
63
	if ( isset( $attributes['className'] ) ) {
64
		$classes .= ' ' . $attributes['className'];
65
	}
66
67
	if ( '' !== $attributes['textColor'] || '' !== $attributes['customTextColor'] ) {
68
		$classes .= ' has-text-color';
69
	}
70
	if ( '' !== $attributes['textColor'] ) {
71
		$classes .= ' has-' . $attributes['textColor'] . '-color';
72
	}
73
74
	$styles = '';
75
76
	if ( '' !== $attributes['customTextColor'] ) {
77
		$styles = 'color: ' . $attributes['customTextColor'] . ';';
78
	}
79
	$articles_rest_url = add_query_arg(
80
		array_merge(
81
			array_map(
82
				function ( $attribute ) {
83
					return false === $attribute ? '0' : str_replace( '#', '%23', $attribute );
84
				},
85
				$attributes
86
			),
87
			array(
88
				'page' => 2,
89
				'amp'  => \Newspack_Blocks::is_amp(),
90
			)
91
		),
92
		rest_url( '/newspack-blocks/v1/articles' )
93
	);
94
95
	$page = $article_query->paged;
96
	if ( ! isset( $page ) ) {
97
		$page = 1;
98
	}
99
100
	$has_more_pages = ( ++$page ) <= $article_query->max_num_pages;
101
102
	/**
103
	 * Hide the "More" button on private sites.
104
	 *
105
	 * Client-side fetching from a private WP.com blog requires authentication,
106
	 * which is not provided in the current implementation.
107
	 * See https://github.com/Automattic/newspack-blocks/issues/306.
108
	 */
109
	$is_blog_private = (int) get_option( 'blog_public' ) === -1;
110
111
	$has_more_button = ! $is_blog_private && $has_more_pages && (bool) $attributes['moreButton'];
112
113
	if ( $has_more_button ) {
114
		$classes .= ' has-more-button';
115
	}
116
117
	ob_start();
118
119
	if ( $article_query->have_posts() ) : ?>
120
		<?php if ( $has_more_button && \Newspack_Blocks::is_amp() ) : ?>
121
			<amp-script layout="container" src="<?php echo esc_url( plugins_url( '/newspack-blocks/amp/homepage-articles/view.js' ) ); ?>">
122
		<?php endif; ?>
123
		<div
124
			class="<?php echo esc_attr( $classes ); ?>"
125
			style="<?php echo esc_attr( $styles ); ?>"
126
			>
127
			<div data-posts data-current-post-id="<?php the_ID(); ?>">
128
				<?php if ( '' !== $attributes['sectionHeader'] ) : ?>
129
					<h2 class="article-section-title">
130
						<span><?php echo wp_kses_post( $attributes['sectionHeader'] ); ?></span>
131
					</h2>
132
				<?php endif; ?>
133
				<?php
134
				echo wp_kses_post(
135
					\Newspack_Blocks::template_inc(
136
						__DIR__ . '/templates/articles-list.php',
137
						array(
0 ignored issues
show
Unused Code introduced by
The call to Newspack_Blocks::template_inc() has too many arguments starting with array('articles_rest_url...ibutes' => $attributes).

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
138
							'articles_rest_url' => $articles_rest_url,
139
							'article_query'     => $article_query,
140
							'attributes'        => $attributes,
141
						)
142
					)
143
				);
144
				?>
145
			</div>
146
			<?php
147
148
			if ( $has_more_button ) :
149
				?>
150
				<button type="button" data-next="<?php echo esc_url( $articles_rest_url ); ?>">
151
				<?php
152
				if ( ! empty( $attributes['moreButtonText'] ) ) {
153
					echo esc_html( $attributes['moreButtonText'] );
154
				} else {
155
					esc_html_e( 'Load more posts', 'jetpack' );
156
				}
157
				?>
158
				</button>
159
				<p class="loading">
160
					<?php esc_html_e( 'Loading…', 'jetpack' ); ?>
161
				</p>
162
				<p class="error">
163
					<?php esc_html_e( 'Something went wrong. Please refresh the page and/or try again.', 'jetpack' ); ?>
164
				</p>
165
166
			<?php endif; ?>
167
168
		</div>
169
		<?php if ( $has_more_button && \Newspack_Blocks::is_amp() ) : ?>
170
			</amp-script>
171
		<?php endif; ?>
172
		<?php
173
	endif;
174
175
	$content = ob_get_clean();
176
	\Newspack_Blocks::enqueue_view_assets( 'homepage-articles' );
177
178
	return $content;
179
}
180
181
/**
182
 * Registers the `newspack-blocks/homepage-articles` block on server.
183
 */
184
function newspack_blocks_register_homepage_articles() {
185
	$block = json_decode(
186
		file_get_contents( __DIR__ . '/block.json' ), // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
187
		true
188
	);
189
	register_block_type(
190
		apply_filters( 'newspack_blocks_block_name', 'jetpack/' . $block['name'] ),
191
		apply_filters(
192
			'newspack_blocks_block_args',
193
			array(
194
				'attributes'      => $block['attributes'],
195
				'render_callback' => __NAMESPACE__ . '\newspack_blocks_render_block_homepage_articles',
196
				'supports'        => array(),
197
			),
198
			$block['name']
0 ignored issues
show
Unused Code introduced by
The call to apply_filters() has too many arguments starting with $block['name'].

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
199
		)
200
	);
201
}
202
add_action( 'init', __NAMESPACE__ . '\newspack_blocks_register_homepage_articles' );
203
204
/**
205
 * Renders author avatar markup.
206
 *
207
 * @param array $author_info Author info array.
208
 *
209
 * @return string Returns formatted Avatar markup
210
 */
211
function newspack_blocks_format_avatars( $author_info ) {
212
	$elements = array_map(
213
		function ( $author ) {
214
			return sprintf( '<a href="%s">%s</a>', $author->url, $author->avatar );
215
		},
216
		$author_info
217
	);
218
219
	return implode( '', $elements );
220
}
221
222
/**
223
 * Renders byline markup.
224
 *
225
 * @param array $author_info Author info array.
226
 *
227
 * @return string Returns byline markup.
228
 */
229
function newspack_blocks_format_byline( $author_info ) {
230
	$index    = -1;
231
	$elements = array_merge(
232
		array(
233
			esc_html_x( 'by', 'post author', 'jetpack' ) . ' ',
234
		),
235
		array_reduce(
236
			$author_info,
237
			function ( $accumulator, $author ) use ( $author_info, &$index ) {
238
				$index ++;
239
				$penultimate = count( $author_info ) - 2;
240
241
				$get_author_posts_url = get_author_posts_url( $author->ID );
242
				if ( function_exists( 'coauthors_posts_links' ) ) {
243
					$get_author_posts_url = get_author_posts_url( $author->ID, $author->user_nicename );
244
				}
245
246
				return array_merge(
247
					$accumulator,
248
					array(
249
						sprintf(
250
							/* translators: 1: author link. 2: author name. 3. variable seperator (comma, 'and', or empty) */
251
							'<span class="author vcard"><a class="url fn n" href="%1$s">%2$s</a></span>',
252
							esc_url( $get_author_posts_url ),
253
							esc_html( $author->display_name )
254
						),
255
						( $index < $penultimate ) ? ', ' : '',
256
						( count( $author_info ) > 1 && $penultimate === $index ) ? esc_html_x( ' and ', 'post author', 'jetpack' ) : '',
257
					)
258
				);
259
			},
260
			array()
261
		)
262
	);
263
264
	return implode( '', $elements );
265
}
266
267
/**
268
 * Inject amp-state containing all post IDs visible on page load.
269
 */
270
function newspack_blocks_inject_amp_state() {
271
	if ( ! \Newspack_Blocks::is_amp() ) {
272
		return;
273
	}
274
	global $newspack_blocks_post_id;
275
	if ( ! $newspack_blocks_post_id || ! count( $newspack_blocks_post_id ) ) {
276
		return;
277
	}
278
	$post_ids = implode( ', ', array_merge( array_keys( $newspack_blocks_post_id ), array( get_the_ID() ) ) );
279
	ob_start();
280
	?>
281
	<amp-state id='newspackHomepagePosts'>
282
		<script type="application/json">
283
			{
284
				"exclude_ids": [ <?php echo esc_attr( $post_ids ); ?> ]
285
			}
286
		</script>
287
	</amp-state>
288
	<?php
289
	echo ob_get_clean(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
290
}
291
292
add_action( 'wp_footer', __NAMESPACE__ . '\newspack_blocks_inject_amp_state' );
293