Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
100.00% |
46 / 46 |
|
100.00% |
3 / 3 |
CRAP | |
100.00% |
1 / 1 |
| Video_Block_Email_Renderer | |
100.00% |
46 / 46 |
|
100.00% |
3 / 3 |
14 | |
100.00% |
1 / 1 |
| render | |
100.00% |
24 / 24 |
|
100.00% |
1 / 1 |
8 | |||
| render_link | |
100.00% |
17 / 17 |
|
100.00% |
1 / 1 |
3 | |||
| get_videopress_url | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * VideoPress video block email renderer class. |
| 4 | * |
| 5 | * @package automattic/jetpack-videopress |
| 6 | */ |
| 7 | |
| 8 | namespace Automattic\Jetpack\VideoPress; |
| 9 | |
| 10 | /** |
| 11 | * Handles rendering VideoPress video blocks for email contexts. |
| 12 | */ |
| 13 | class Video_Block_Email_Renderer { |
| 14 | |
| 15 | /** |
| 16 | * Render VideoPress video block for email. |
| 17 | * |
| 18 | * @param string $block_content The original block HTML content. |
| 19 | * @param array $parsed_block The parsed block data including attributes. |
| 20 | * @param object $rendering_context Email rendering context. |
| 21 | * |
| 22 | * @return string |
| 23 | */ |
| 24 | public static function render( $block_content, $parsed_block, $rendering_context ) { |
| 25 | // Validate input parameters and required dependencies. |
| 26 | if ( ! isset( $parsed_block['attrs'] ) || ! is_array( $parsed_block['attrs'] ) || |
| 27 | ! class_exists( '\Automattic\WooCommerce\EmailEditor\Integrations\Core\Renderer\Blocks\Embed' ) ) { |
| 28 | return ''; |
| 29 | } |
| 30 | |
| 31 | $attributes = $parsed_block['attrs']; |
| 32 | |
| 33 | // Get the VideoPress URL from the guid attribute. |
| 34 | $videopress_url = self::get_videopress_url( $attributes ); |
| 35 | |
| 36 | if ( empty( $videopress_url ) ) { |
| 37 | return ''; |
| 38 | } |
| 39 | |
| 40 | // For private videos, render a simple link to the post since the video isn't accessible on VideoPress. |
| 41 | // The isPrivate attribute is pre-computed by the block editor based on video and site settings. |
| 42 | if ( isset( $attributes['isPrivate'] ) && true === $attributes['isPrivate'] ) { |
| 43 | return self::render_link( $parsed_block ); |
| 44 | } |
| 45 | |
| 46 | // Create a mock embed block structure that WooCommerce's embed renderer can handle. |
| 47 | // The embed renderer will detect VideoPress from the URL and render it appropriately. |
| 48 | $mock_embed_block = array( |
| 49 | 'blockName' => 'core/embed', |
| 50 | 'attrs' => array( |
| 51 | 'url' => $videopress_url, |
| 52 | 'providerNameSlug' => 'videopress', |
| 53 | ), |
| 54 | 'innerHTML' => sprintf( |
| 55 | '<figure class="wp-block-embed is-type-video is-provider-videopress"><div class="wp-block-embed__wrapper">%s</div></figure>', |
| 56 | esc_url( $videopress_url ) |
| 57 | ), |
| 58 | ); |
| 59 | |
| 60 | // Preserve email_attrs if present (used for spacing/width calculations). |
| 61 | if ( ! empty( $parsed_block['email_attrs'] ) ) { |
| 62 | $mock_embed_block['email_attrs'] = $parsed_block['email_attrs']; |
| 63 | } |
| 64 | |
| 65 | // Use WooCommerce's core embed renderer. |
| 66 | // @phan-suppress-next-line PhanUndeclaredClassMethod -- Optional WooCommerce dependency, checked with class_exists() above. |
| 67 | $woo_embed_renderer = new \Automattic\WooCommerce\EmailEditor\Integrations\Core\Renderer\Blocks\Embed(); |
| 68 | |
| 69 | // @phan-suppress-next-line PhanUndeclaredClassMethod -- Optional WooCommerce dependency, checked with class_exists() above. |
| 70 | return $woo_embed_renderer->render( $mock_embed_block['innerHTML'], $mock_embed_block, $rendering_context ); |
| 71 | } |
| 72 | |
| 73 | /** |
| 74 | * Render a simple link for private VideoPress videos in emails. |
| 75 | * Links to the post containing the video since private videos aren't accessible on VideoPress. |
| 76 | * |
| 77 | * @param array $parsed_block The parsed block data. |
| 78 | * |
| 79 | * @return string The rendered link HTML. |
| 80 | */ |
| 81 | private static function render_link( $parsed_block ) { |
| 82 | $post_url = get_the_permalink(); |
| 83 | |
| 84 | if ( empty( $post_url ) ) { |
| 85 | return ''; |
| 86 | } |
| 87 | |
| 88 | $link_text = __( 'Visit the post to watch the video', 'jetpack-videopress-pkg' ); |
| 89 | |
| 90 | $link_html = sprintf( |
| 91 | '<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>', |
| 92 | esc_url( $post_url ), |
| 93 | esc_html( $link_text ) |
| 94 | ); |
| 95 | |
| 96 | // Wrap with spacing if email_attrs are present. |
| 97 | $email_attrs = $parsed_block['email_attrs'] ?? array(); |
| 98 | if ( ! empty( $email_attrs['padding'] ) ) { |
| 99 | $link_html = sprintf( |
| 100 | '<p style="padding: %s;">%s</p>', |
| 101 | esc_attr( $email_attrs['padding'] ), |
| 102 | $link_html |
| 103 | ); |
| 104 | } |
| 105 | |
| 106 | return $link_html; |
| 107 | } |
| 108 | |
| 109 | /** |
| 110 | * Get the VideoPress URL from block attributes for email rendering. |
| 111 | * |
| 112 | * @param array $attributes Block attributes. |
| 113 | * |
| 114 | * @return string VideoPress URL or empty string. |
| 115 | */ |
| 116 | private static function get_videopress_url( $attributes ) { |
| 117 | // Construct URL from guid attribute. |
| 118 | if ( ! empty( $attributes['guid'] ) ) { |
| 119 | $guid = $attributes['guid']; |
| 120 | |
| 121 | // VideoPress guids are alphanumeric only (e.g., "nfbj0J36"). |
| 122 | // Validate format to prevent any injection issues. |
| 123 | if ( preg_match( '/^[a-zA-Z0-9]+$/', $guid ) ) { |
| 124 | return 'https://videopress.com/v/' . $guid; |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | return ''; |
| 129 | } |
| 130 | } |