Automattic\WooCommerce\EmailEditor\Integrations\Core\Renderer\Blocks

Audio::render_content │ protected │ WC 1.0

Renders the audio block content as an audio player for email.

Method of the class: Audio{}

No Hooks.

Returns

string.

Usage

// protected - for code of main (parent) or child class
$result = $this->render_content( $block_content, $parsed_block, $rendering_context ): string;
$block_content(string) (required)
Block content.
$parsed_block(array) (required)
Parsed block.
$rendering_context(Rendering_Context) (required)
Rendering context (required by parent contract but unused in this implementation).

Audio::render_content() code WC 11.1.2

protected function render_content( string $block_content, array $parsed_block, Rendering_Context $rendering_context ): string { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
	$attr = $parsed_block['attrs'];

	// Get URL and length.
	if ( isset( $attr['id'] ) ) {
		// Audio file from site's media library.
		$url    = \wp_get_attachment_url( $attr['id'] );
		$meta   = \get_post_meta( $attr['id'], '_wp_attachment_metadata', true );
		$length = ( is_array( $meta ) && isset( $meta['length_formatted'] ) && is_string( $meta['length_formatted'] ) ) ? $meta['length_formatted'] : '';
	} else {
		// Audio file from external URL.
		preg_match( '#<audio[^>]*\ssrc=["\']([^"\']*)["\'][^>]*/?>#', $block_content, $audio );
		$url    = isset( $audio[1] ) ? $audio[1] : $attr['src'] ?? '';
		$length = null;
	}

	// Validate URL with proper ordering and comprehensive checks.
	if ( empty( $url ) ) {
		return '';
	}

	// Validate URL type and format.
	if ( ! str_starts_with( $url, 'data:audio/' ) &&
		! str_starts_with( $url, '/' ) &&
		! str_starts_with( $url, 'https://' ) ) {
		// Reject everything else (http://, ftp://, relative paths, etc.).
		return '';
	}

	// For HTTPS URLs, validate with wp_http_validate_url.
	if ( str_starts_with( $url, 'https://' ) && ! wp_http_validate_url( $url ) ) {
		return '';
	}

	// Get spacing from email_attrs for better consistency with core blocks.
	$email_attrs        = $parsed_block['email_attrs'] ?? array();
	$table_margin_style = '';

	if ( ! empty( $email_attrs ) && class_exists( '\WP_Style_Engine' ) ) {
		// Get margin for table styling.
		$table_margin_style = \WP_Style_Engine::compile_css( array_intersect_key( $email_attrs, array_flip( array( 'margin' ) ) ), '' );
	}

	$icon_image = $this->get_audio_icon_url();
	$label      = ! empty( $attr['label'] ) ? $attr['label'] : __( 'Listen to the audio', 'woocommerce' );

	// Add duration to label if available.
	if ( ! empty( $length ) ) {
		$label .= ' (' . esc_html( (string) $length ) . ')';
	}

	$audio_url = esc_url( $url );

	// Define pill-style colors and styling.
	$background_color = '#f6f7f7';
	$border_color     = '#AAA';
	$icon_size        = '18px';
	$font_size        = '14px';
	$start_side       = $rendering_context->get_start_side();
	$end_side         = $rendering_context->get_end_side();

	// Generate the icon content.
	$icon_content = sprintf(
		'<a href="%1$s" rel="noopener nofollow" target="_blank" style="padding: 0.25em; padding-%5$s: 17px; display: inline-block; vertical-align: middle;"><img height="%2$s" src="%3$s" style="display:block;margin-%6$s:0;vertical-align:middle;" width="%2$s" alt="%4$s"></a>',
		$audio_url,
		esc_attr( $icon_size ),
		esc_url( $icon_image ),
		// translators: %s is the audio player icon.
		sprintf( __( '%s icon', 'woocommerce' ), __( 'Audio', 'woocommerce' ) ),
		esc_attr( $start_side ),
		esc_attr( $end_side )
	);
	$icon_content = Table_Wrapper_Helper::render_table_cell( $icon_content, array( 'style' => sprintf( 'vertical-align:middle;font-size:%s;', $font_size ) ) );

	// Generate the label content.
	$label_content    = sprintf(
		'<a href="%1$s" rel="noopener nofollow" target="_blank" style="text-decoration:none; padding: 0.25em; padding-%3$s: 17px; display: inline-block;"><span style="margin-left:.5em;margin-right:.5em;font-weight:bold"> %2$s </span></a>',
		$audio_url,
		esc_html( $label ),
		esc_attr( $end_side )
	);
	$label_cell_style = sprintf(
		'vertical-align:middle;font-size:%s;',
		$font_size
	);
	$label_content    = Table_Wrapper_Helper::render_table_cell( $label_content, array( 'style' => $label_cell_style ) );

	// Combine icon and label tables.
	$audio_content = $icon_content . $label_content;

	// Create the main pill-style table.
	$main_table_styles = sprintf(
		'background-color: %s; border-radius: 9999px; float: none; border: 1px solid %s; border-collapse: separate;',
		$background_color,
		$border_color
	);

	$main_table_attrs = array(
		'align' => $rendering_context->get_default_text_align(),
		'style' => $main_table_styles,
	);

	$main_table = Table_Wrapper_Helper::render_table_wrapper( $audio_content, $main_table_attrs, array(), array(), false );

	// Create the main wrapper table.
	$table_style = 'width: 100%;';
	if ( ! empty( $table_margin_style ) ) {
		$table_style = $table_margin_style . '; ' . $table_style;
	} else {
		$table_style = 'margin: 16px 0; ' . $table_style;
	}

	$table_attrs = array(
		'style' => $table_style,
	);

	$cell_attrs = array(
		'style' => 'min-width: 100%; vertical-align: middle; word-break: break-word; text-align: ' . $rendering_context->get_default_text_align() . ';',
	);

	$main_wrapper = Table_Wrapper_Helper::render_table_wrapper( $main_table, $table_attrs, $cell_attrs );

	return Table_Wrapper_Helper::render_outlook_table_wrapper( $main_wrapper, array( 'align' => $rendering_context->get_default_text_align() ) );
}