wp/wp-includes/blocks/post-featured-image.php
changeset 21 48c4eec2b7e6
parent 19 3d72ae0968f4
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
     5  * @package WordPress
     5  * @package WordPress
     6  */
     6  */
     7 
     7 
     8 /**
     8 /**
     9  * Renders the `core/post-featured-image` block on the server.
     9  * Renders the `core/post-featured-image` block on the server.
       
    10  *
       
    11  * @since 5.8.0
    10  *
    12  *
    11  * @param array    $attributes Block attributes.
    13  * @param array    $attributes Block attributes.
    12  * @param string   $content    Block default content.
    14  * @param string   $content    Block default content.
    13  * @param WP_Block $block      Block instance.
    15  * @param WP_Block $block      Block instance.
    14  * @return string Returns the featured image for the current post.
    16  * @return string Returns the featured image for the current post.
    17 	if ( ! isset( $block->context['postId'] ) ) {
    19 	if ( ! isset( $block->context['postId'] ) ) {
    18 		return '';
    20 		return '';
    19 	}
    21 	}
    20 	$post_ID = $block->context['postId'];
    22 	$post_ID = $block->context['postId'];
    21 
    23 
       
    24 	$is_link        = isset( $attributes['isLink'] ) && $attributes['isLink'];
    22 	$size_slug      = isset( $attributes['sizeSlug'] ) ? $attributes['sizeSlug'] : 'post-thumbnail';
    25 	$size_slug      = isset( $attributes['sizeSlug'] ) ? $attributes['sizeSlug'] : 'post-thumbnail';
    23 	$post_title     = trim( strip_tags( get_the_title( $post_ID ) ) );
    26 	$attr           = get_block_core_post_featured_image_border_attributes( $attributes );
    24 	$featured_image = get_the_post_thumbnail( $post_ID, $size_slug, array( 'alt' => $post_title ) );
    27 	$overlay_markup = get_block_core_post_featured_image_overlay_element_markup( $attributes );
       
    28 
       
    29 	if ( $is_link ) {
       
    30 		if ( get_the_title( $post_ID ) ) {
       
    31 			$attr['alt'] = trim( strip_tags( get_the_title( $post_ID ) ) );
       
    32 		} else {
       
    33 			$attr['alt'] = sprintf(
       
    34 				// translators: %d is the post ID.
       
    35 				__( 'Untitled post %d' ),
       
    36 				$post_ID
       
    37 			);
       
    38 		}
       
    39 	}
       
    40 
       
    41 	$extra_styles = '';
       
    42 
       
    43 	// Aspect ratio with a height set needs to override the default width/height.
       
    44 	if ( ! empty( $attributes['aspectRatio'] ) ) {
       
    45 		$extra_styles .= 'width:100%;height:100%;';
       
    46 	} elseif ( ! empty( $attributes['height'] ) ) {
       
    47 		$extra_styles .= "height:{$attributes['height']};";
       
    48 	}
       
    49 
       
    50 	if ( ! empty( $attributes['scale'] ) ) {
       
    51 		$extra_styles .= "object-fit:{$attributes['scale']};";
       
    52 	}
       
    53 	if ( ! empty( $attributes['style']['shadow'] ) ) {
       
    54 		$shadow_styles = wp_style_engine_get_styles( array( 'shadow' => $attributes['style']['shadow'] ) );
       
    55 
       
    56 		if ( ! empty( $shadow_styles['css'] ) ) {
       
    57 			$extra_styles .= $shadow_styles['css'];
       
    58 		}
       
    59 	}
       
    60 
       
    61 	if ( ! empty( $extra_styles ) ) {
       
    62 		$attr['style'] = empty( $attr['style'] ) ? $extra_styles : $attr['style'] . $extra_styles;
       
    63 	}
       
    64 
       
    65 	$featured_image = get_the_post_thumbnail( $post_ID, $size_slug, $attr );
       
    66 
       
    67 	// Get the first image from the post.
       
    68 	if ( $attributes['useFirstImageFromPost'] && ! $featured_image ) {
       
    69 		$content_post = get_post( $post_ID );
       
    70 		$content      = $content_post->post_content;
       
    71 		$processor    = new WP_HTML_Tag_Processor( $content );
       
    72 
       
    73 		/*
       
    74 		 * Transfer the image tag from the post into a new text snippet.
       
    75 		 * Because the HTML API doesn't currently expose a way to extract
       
    76 		 * HTML substrings this is necessary as a workaround. Of note, this
       
    77 		 * is different than directly extracting the IMG tag:
       
    78 		 * - If there are duplicate attributes in the source there will only be one in the output.
       
    79 		 * - If there are single-quoted or unquoted attributes they will be double-quoted in the output.
       
    80 		 * - If there are named character references in the attribute values they may be replaced with their direct code points. E.g. `…` becomes `…`.
       
    81 		 * In the future there will likely be a mechanism to copy snippets of HTML from
       
    82 		 * one document into another, via the HTML Processor's `get_outer_html()` or
       
    83 		 * equivalent. When that happens it would be appropriate to replace this custom
       
    84 		 * code with that canonical code.
       
    85 		 */
       
    86 		if ( $processor->next_tag( 'img' ) ) {
       
    87 			$tag_html = new WP_HTML_Tag_Processor( '<img>' );
       
    88 			$tag_html->next_tag();
       
    89 			foreach ( $processor->get_attribute_names_with_prefix( '' ) as $name ) {
       
    90 				$tag_html->set_attribute( $name, $processor->get_attribute( $name ) );
       
    91 			}
       
    92 			$featured_image = $tag_html->get_updated_html();
       
    93 		}
       
    94 	}
       
    95 
    25 	if ( ! $featured_image ) {
    96 	if ( ! $featured_image ) {
    26 		return '';
    97 		return '';
    27 	}
    98 	}
    28 	$wrapper_attributes = get_block_wrapper_attributes();
    99 
    29 	if ( isset( $attributes['isLink'] ) && $attributes['isLink'] ) {
   100 	if ( $is_link ) {
    30 		$featured_image = sprintf( '<a href="%1s">%2s</a>', get_the_permalink( $post_ID ), $featured_image );
   101 		$link_target    = $attributes['linkTarget'];
    31 	}
   102 		$rel            = ! empty( $attributes['rel'] ) ? 'rel="' . esc_attr( $attributes['rel'] ) . '"' : '';
    32 
   103 		$height         = ! empty( $attributes['height'] ) ? 'style="' . esc_attr( safecss_filter_attr( 'height:' . $attributes['height'] ) ) . '"' : '';
    33 	$has_width  = ! empty( $attributes['width'] );
   104 		$featured_image = sprintf(
    34 	$has_height = ! empty( $attributes['height'] );
   105 			'<a href="%1$s" target="%2$s" %3$s %4$s>%5$s%6$s</a>',
    35 	if ( ! $has_height && ! $has_width ) {
   106 			get_the_permalink( $post_ID ),
    36 		return "<figure $wrapper_attributes>$featured_image</figure>";
   107 			esc_attr( $link_target ),
    37 	}
   108 			$rel,
    38 
   109 			$height,
    39 	if ( $has_width ) {
   110 			$featured_image,
    40 		$wrapper_attributes = get_block_wrapper_attributes( array( 'style' => "width:{$attributes['width']};" ) );
   111 			$overlay_markup
    41 	}
   112 		);
    42 
   113 	} else {
    43 	if ( $has_height ) {
   114 		$featured_image = $featured_image . $overlay_markup;
    44 		$image_styles = "height:{$attributes['height']};";
   115 	}
    45 		if ( ! empty( $attributes['scale'] ) ) {
   116 
    46 			$image_styles .= "object-fit:{$attributes['scale']};";
   117 	$aspect_ratio = ! empty( $attributes['aspectRatio'] )
    47 		}
   118 		? esc_attr( safecss_filter_attr( 'aspect-ratio:' . $attributes['aspectRatio'] ) ) . ';'
    48 		$featured_image = str_replace( 'src=', 'style="' . esc_attr( $image_styles ) . '" src=', $featured_image );
   119 		: '';
    49 	}
   120 	$width        = ! empty( $attributes['width'] )
    50 
   121 		? esc_attr( safecss_filter_attr( 'width:' . $attributes['width'] ) ) . ';'
    51 	return "<figure $wrapper_attributes>$featured_image</figure>";
   122 		: '';
       
   123 	$height       = ! empty( $attributes['height'] )
       
   124 		? esc_attr( safecss_filter_attr( 'height:' . $attributes['height'] ) ) . ';'
       
   125 		: '';
       
   126 	if ( ! $height && ! $width && ! $aspect_ratio ) {
       
   127 		$wrapper_attributes = get_block_wrapper_attributes();
       
   128 	} else {
       
   129 		$wrapper_attributes = get_block_wrapper_attributes( array( 'style' => $aspect_ratio . $width . $height ) );
       
   130 	}
       
   131 	return "<figure {$wrapper_attributes}>{$featured_image}</figure>";
       
   132 }
       
   133 
       
   134 /**
       
   135  * Generate markup for the HTML element that will be used for the overlay.
       
   136  *
       
   137  * @since 6.1.0
       
   138  *
       
   139  * @param array $attributes Block attributes.
       
   140  *
       
   141  * @return string HTML markup in string format.
       
   142  */
       
   143 function get_block_core_post_featured_image_overlay_element_markup( $attributes ) {
       
   144 	$has_dim_background  = isset( $attributes['dimRatio'] ) && $attributes['dimRatio'];
       
   145 	$has_gradient        = isset( $attributes['gradient'] ) && $attributes['gradient'];
       
   146 	$has_custom_gradient = isset( $attributes['customGradient'] ) && $attributes['customGradient'];
       
   147 	$has_solid_overlay   = isset( $attributes['overlayColor'] ) && $attributes['overlayColor'];
       
   148 	$has_custom_overlay  = isset( $attributes['customOverlayColor'] ) && $attributes['customOverlayColor'];
       
   149 	$class_names         = array( 'wp-block-post-featured-image__overlay' );
       
   150 	$styles              = array();
       
   151 
       
   152 	if ( ! $has_dim_background ) {
       
   153 		return '';
       
   154 	}
       
   155 
       
   156 	// Apply border classes and styles.
       
   157 	$border_attributes = get_block_core_post_featured_image_border_attributes( $attributes );
       
   158 
       
   159 	if ( ! empty( $border_attributes['class'] ) ) {
       
   160 		$class_names[] = $border_attributes['class'];
       
   161 	}
       
   162 
       
   163 	if ( ! empty( $border_attributes['style'] ) ) {
       
   164 		$styles[] = $border_attributes['style'];
       
   165 	}
       
   166 
       
   167 	// Apply overlay and gradient classes.
       
   168 	if ( $has_dim_background ) {
       
   169 		$class_names[] = 'has-background-dim';
       
   170 		$class_names[] = "has-background-dim-{$attributes['dimRatio']}";
       
   171 	}
       
   172 
       
   173 	if ( $has_solid_overlay ) {
       
   174 		$class_names[] = "has-{$attributes['overlayColor']}-background-color";
       
   175 	}
       
   176 
       
   177 	if ( $has_gradient || $has_custom_gradient ) {
       
   178 		$class_names[] = 'has-background-gradient';
       
   179 	}
       
   180 
       
   181 	if ( $has_gradient ) {
       
   182 		$class_names[] = "has-{$attributes['gradient']}-gradient-background";
       
   183 	}
       
   184 
       
   185 	// Apply background styles.
       
   186 	if ( $has_custom_gradient ) {
       
   187 		$styles[] = sprintf( 'background-image: %s;', $attributes['customGradient'] );
       
   188 	}
       
   189 
       
   190 	if ( $has_custom_overlay ) {
       
   191 		$styles[] = sprintf( 'background-color: %s;', $attributes['customOverlayColor'] );
       
   192 	}
       
   193 
       
   194 	return sprintf(
       
   195 		'<span class="%s" style="%s" aria-hidden="true"></span>',
       
   196 		esc_attr( implode( ' ', $class_names ) ),
       
   197 		esc_attr( safecss_filter_attr( implode( ' ', $styles ) ) )
       
   198 	);
       
   199 }
       
   200 
       
   201 /**
       
   202  * Generates class names and styles to apply the border support styles for
       
   203  * the Post Featured Image block.
       
   204  *
       
   205  * @since 6.1.0
       
   206  *
       
   207  * @param array $attributes The block attributes.
       
   208  * @return array The border-related classnames and styles for the block.
       
   209  */
       
   210 function get_block_core_post_featured_image_border_attributes( $attributes ) {
       
   211 	$border_styles = array();
       
   212 	$sides         = array( 'top', 'right', 'bottom', 'left' );
       
   213 
       
   214 	// Border radius.
       
   215 	if ( isset( $attributes['style']['border']['radius'] ) ) {
       
   216 		$border_styles['radius'] = $attributes['style']['border']['radius'];
       
   217 	}
       
   218 
       
   219 	// Border style.
       
   220 	if ( isset( $attributes['style']['border']['style'] ) ) {
       
   221 		$border_styles['style'] = $attributes['style']['border']['style'];
       
   222 	}
       
   223 
       
   224 	// Border width.
       
   225 	if ( isset( $attributes['style']['border']['width'] ) ) {
       
   226 		$border_styles['width'] = $attributes['style']['border']['width'];
       
   227 	}
       
   228 
       
   229 	// Border color.
       
   230 	$preset_color           = array_key_exists( 'borderColor', $attributes ) ? "var:preset|color|{$attributes['borderColor']}" : null;
       
   231 	$custom_color           = $attributes['style']['border']['color'] ?? null;
       
   232 	$border_styles['color'] = $preset_color ? $preset_color : $custom_color;
       
   233 
       
   234 	// Individual border styles e.g. top, left etc.
       
   235 	foreach ( $sides as $side ) {
       
   236 		$border                 = $attributes['style']['border'][ $side ] ?? null;
       
   237 		$border_styles[ $side ] = array(
       
   238 			'color' => isset( $border['color'] ) ? $border['color'] : null,
       
   239 			'style' => isset( $border['style'] ) ? $border['style'] : null,
       
   240 			'width' => isset( $border['width'] ) ? $border['width'] : null,
       
   241 		);
       
   242 	}
       
   243 
       
   244 	$styles     = wp_style_engine_get_styles( array( 'border' => $border_styles ) );
       
   245 	$attributes = array();
       
   246 	if ( ! empty( $styles['classnames'] ) ) {
       
   247 		$attributes['class'] = $styles['classnames'];
       
   248 	}
       
   249 	if ( ! empty( $styles['css'] ) ) {
       
   250 		$attributes['style'] = $styles['css'];
       
   251 	}
       
   252 	return $attributes;
    52 }
   253 }
    53 
   254 
    54 /**
   255 /**
    55  * Registers the `core/post-featured-image` block on the server.
   256  * Registers the `core/post-featured-image` block on the server.
       
   257  *
       
   258  * @since 5.8.0
    56  */
   259  */
    57 function register_block_core_post_featured_image() {
   260 function register_block_core_post_featured_image() {
    58 	register_block_type_from_metadata(
   261 	register_block_type_from_metadata(
    59 		__DIR__ . '/post-featured-image',
   262 		__DIR__ . '/post-featured-image',
    60 		array(
   263 		array(