PluginProbe
Gutenberg / 22.3.0
Gutenberg v22.3.0
23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 7.4.0 All 402 releases
gutenberg / build / scripts / block-library / cover.php

cover.php in Gutenberg 22.3.0, at build/scripts/block-library/cover.php

208 lines 7.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Server-side rendering of the `core/cover` block.
4 *
5 * @package WordPress
6 */
7
8 /**
9 * Renders the `core/cover` block on server.
10 *
11 * @since 6.0.0
12 *
13 * @param array $attributes The block attributes.
14 * @param string $content The block rendered content.
15 *
16 * @return string Returns the cover block markup, if useFeaturedImage is true.
17 */
18 function gutenberg_render_block_core_cover( $attributes, $content ) {
19 // Handle embed video background.
20 if (
21 isset( $attributes['backgroundType'] ) &&
22 'embed-video' === $attributes['backgroundType'] &&
23 isset( $attributes['url'] ) &&
24 ! empty( $attributes['url'] ) &&
25 is_string( $attributes['url'] )
26 ) {
27 $url = $attributes['url'];
28
29 // Use WordPress's native oEmbed processing (includes caching).
30 $oembed_html = wp_oembed_get( $url );
31
32 if ( $oembed_html ) {
33 // Extract iframe src from the oEmbed HTML.
34 preg_match( '/src=["\']([^"\']+)["\']/', $oembed_html, $src_matches );
35 if ( ! empty( $src_matches[1] ) ) {
36 $iframe_src = $src_matches[1];
37
38 // Detect provider from iframe src URL.
39 $lower_src = strtolower( $iframe_src );
40 $provider = null;
41
42 if ( strpos( $lower_src, 'youtube.com' ) !== false || strpos( $lower_src, 'youtu.be' ) !== false ) {
43 $provider = 'youtube';
44 } elseif ( strpos( $lower_src, 'vimeo.com' ) !== false ) {
45 $provider = 'vimeo';
46 } elseif ( strpos( $lower_src, 'videopress.com' ) !== false ) {
47 $provider = 'videopress';
48 } elseif ( strpos( $lower_src, 'wordpress.tv' ) !== false ) {
49 $provider = 'wordpress-tv';
50 }
51
52 // Modify iframe src to add background video parameters based on provider.
53 $parsed_url = wp_parse_url( $iframe_src );
54 if ( $parsed_url && isset( $parsed_url['host'] ) ) {
55 // Parse existing query parameters.
56 $query_params = array();
57 if ( isset( $parsed_url['query'] ) ) {
58 parse_str( $parsed_url['query'], $query_params );
59 }
60
61 // Add background video parameters based on provider.
62 if ( 'youtube' === $provider ) {
63 $query_params['autoplay'] = '1';
64 $query_params['mute'] = '1';
65 $query_params['loop'] = '1';
66 $query_params['controls'] = '0';
67 $query_params['modestbranding'] = '1';
68 $query_params['playsinline'] = '1';
69 } elseif ( 'vimeo' === $provider ) {
70 $query_params['autoplay'] = '1';
71 $query_params['muted'] = '1';
72 $query_params['loop'] = '1';
73 $query_params['background'] = '1';
74 $query_params['controls'] = '0';
75 $query_params['transparent'] = '0';
76 } elseif ( 'videopress' === $provider || 'wordpress-tv' === $provider ) {
77 $query_params['autoplay'] = '1';
78 $query_params['loop'] = '1';
79 $query_params['muted'] = '1';
80 }
81
82 // Rebuild the URL with new parameters.
83 $iframe_src = $parsed_url['scheme'] . '://' . $parsed_url['host'];
84 if ( isset( $parsed_url['path'] ) ) {
85 $iframe_src .= $parsed_url['path'];
86 }
87 if ( ! empty( $query_params ) ) {
88 $iframe_src .= '?' . http_build_query( $query_params );
89 }
90 }
91
92 // Build the iframe HTML that will replace the figure.
93 $iframe_html = sprintf(
94 '<div class="wp-block-cover__video-background wp-block-cover__embed-background"><iframe src="%s" title="Background video" frameborder="0" allow="autoplay; fullscreen"></iframe></div>',
95 esc_url( $iframe_src )
96 );
97
98 // Use the HTML API to find and replace the figure.wp-block-embed element.
99 $processor = new WP_HTML_Tag_Processor( $content );
100
101 if ( $processor->next_tag(
102 array(
103 'tag_name' => 'FIGURE',
104 'class_name' => 'wp-block-embed',
105 )
106 ) ) {
107 // Use regex with PREG_OFFSET_CAPTURE to find the position of the figure element.
108 // This follows the same pattern used for featured image insertion below.
109 $figure_pattern = '/<figure\s+[^>]*\bwp-block-embed\b[^>]*>.*?<\/figure>/is';
110 if ( 1 === preg_match( $figure_pattern, $content, $matches, PREG_OFFSET_CAPTURE ) ) {
111 $figure_start = $matches[0][1];
112 $figure_length = strlen( $matches[0][0] );
113 $figure_end = $figure_start + $figure_length;
114
115 // Replace the figure element with the iframe HTML.
116 $content = substr( $content, 0, $figure_start ) . $iframe_html . substr( $content, $figure_end );
117 }
118 }
119 }
120 }
121
122 return $content;
123 }
124
125 if ( 'image' !== $attributes['backgroundType'] || false === $attributes['useFeaturedImage'] ) {
126 return $content;
127 }
128
129 $object_position = isset( $attributes['focalPoint'] )
130 ? round( $attributes['focalPoint']['x'] * 100 ) . '% ' . round( $attributes['focalPoint']['y'] * 100 ) . '%'
131 : null;
132
133 if ( ! ( $attributes['hasParallax'] || $attributes['isRepeated'] ) ) {
134 $attr = array(
135 'class' => 'wp-block-cover__image-background',
136 'data-object-fit' => 'cover',
137 );
138
139 if ( $object_position ) {
140 $attr['data-object-position'] = $object_position;
141 $attr['style'] = 'object-position:' . $object_position . ';';
142 }
143
144 $image = get_the_post_thumbnail( null, $attributes['sizeSlug'] ?? 'post-thumbnail', $attr );
145 } else {
146 if ( in_the_loop() ) {
147 update_post_thumbnail_cache();
148 }
149 $current_featured_image = get_the_post_thumbnail_url( null, $attributes['sizeSlug'] ?? null );
150 if ( ! $current_featured_image ) {
151 return $content;
152 }
153
154 $current_thumbnail_id = get_post_thumbnail_id();
155
156 $processor = new WP_HTML_Tag_Processor( '<div></div>' );
157 $processor->next_tag();
158
159 $current_alt = trim( strip_tags( get_post_meta( $current_thumbnail_id, '_wp_attachment_image_alt', true ) ) );
160 if ( $current_alt ) {
161 $processor->set_attribute( 'role', 'img' );
162 $processor->set_attribute( 'aria-label', $current_alt );
163 }
164
165 $processor->add_class( 'wp-block-cover__image-background' );
166 $processor->add_class( 'wp-image-' . $current_thumbnail_id );
167 if ( $attributes['hasParallax'] ) {
168 $processor->add_class( 'has-parallax' );
169 }
170 if ( $attributes['isRepeated'] ) {
171 $processor->add_class( 'is-repeated' );
172 }
173
174 $styles = 'background-position:' . ( $object_position ?? '50% 50%' ) . ';';
175 $styles .= 'background-image:url(' . esc_url( $current_featured_image ) . ');';
176 $processor->set_attribute( 'style', $styles );
177
178 $image = $processor->get_updated_html();
179 }
180
181 /*
182 * Inserts the featured image between the (1st) cover 'background' `span` and 'inner_container' `div`,
183 * and removes eventual whitespace characters between the two (typically introduced at template level)
184 */
185 $inner_container_start = '/<div\b[^>]+wp-block-cover__inner-container[\s|"][^>]*>/U';
186 if ( 1 === preg_match( $inner_container_start, $content, $matches, PREG_OFFSET_CAPTURE ) ) {
187 $offset = $matches[0][1];
188 $content = substr( $content, 0, $offset ) . $image . substr( $content, $offset );
189 }
190
191 return $content;
192 }
193
194 /**
195 * Registers the `core/cover` block renderer on server.
196 *
197 * @since 6.0.0
198 */
199 function gutenberg_register_block_core_cover() {
200 register_block_type_from_metadata(
201 __DIR__ . '/cover',
202 array(
203 'render_callback' => 'gutenberg_render_block_core_cover',
204 )
205 );
206 }
207 add_action( 'init', 'gutenberg_register_block_core_cover', 20 );
208