<?php
|
namespace JVBase\blocks;
|
|
if (!defined('ABSPATH')) {
|
exit;
|
}
|
|
/**
|
* Video Cover Block Class
|
*
|
* Handles registration and rendering of self-hosted video cover blocks
|
* with poster images and multiple video format support
|
*/
|
class VideoCoverBlock
|
{
|
protected static ?VideoCoverBlock $instance = null;
|
protected string $path = JVB_DIR . '/build/video-cover';
|
|
public static function getInstance(): VideoCoverBlock
|
{
|
if (self::$instance === null) {
|
self::$instance = new self();
|
}
|
return self::$instance;
|
}
|
|
public function __construct()
|
{
|
add_action('init', [$this, 'registerBlock']);
|
}
|
|
public function registerBlock(): void
|
{
|
register_block_type($this->path, [
|
'render_callback' => [$this, 'render']
|
]);
|
}
|
|
/**
|
* Render the video cover block
|
*/
|
public function render($attributes, $content): string
|
{
|
// Extract attributes with defaults
|
$poster_id = $attributes['posterId'] ?? 0;
|
$video_sources = $attributes['videoSources'] ?? [];
|
$mobile_sources = $attributes['mobileSources'] ?? [];
|
$css_class = $attributes['className'] ?? '';
|
$fade_class = $attributes['fadeEffect'] ?? false ? 'fade' : '';
|
//Get date of current post
|
global $post;
|
$date = date('c',strtotime($post->post_date));
|
$title = $attributes['title'] ?? $post->post_title;
|
$description = $attributes['description'] ?? $post->post_excerpt;
|
|
// If no video sources, return empty
|
if (empty($video_sources)) {
|
return '';
|
}
|
|
|
|
// Get poster URL
|
$poster_url = $poster_id ? wp_get_attachment_url($poster_id) : '';
|
|
// Build video tag
|
$classes = trim("video-cover {$fade_class} {$css_class}");
|
|
$html = '<section class="'.esc_attr($classes).'">
|
<script type="application/ld+json">
|
{
|
"@context": "https://schema.org/",
|
"@type": "VideoObject",
|
"name": "'.$title.'",
|
"thumbnailUrl": "'.$poster_url.'",
|
"contentUrl": "'.$video_sources[0]['url'].'",
|
"description": "'.$description.'",
|
"uploadDate": "'.$date.'"
|
}
|
</script>
|
<div class="wrap">
|
<div class="video-container">';
|
$html .= '<video';
|
$html .= ' muted loop playsinline autoplay';
|
|
if ($poster_url) {
|
$html .= ' poster="' . esc_url($poster_url) . '"';
|
}
|
|
$html .= '>';
|
|
// Add mobile sources first (lower resolution)
|
foreach ($mobile_sources as $source) {
|
if (!empty($source['url']) && !empty($source['mime'])) {
|
$html .= '<source';
|
$html .= ' src="' . esc_url($source['url']) . '"';
|
$html .= ' type="' . esc_attr($source['mime']) . '"';
|
$html .= ' media="(max-width: 767px)"';
|
$html .= '>';
|
}
|
}
|
|
// Add desktop sources
|
foreach ($video_sources as $source) {
|
if (!empty($source['url']) && !empty($source['mime'])) {
|
$html .= '<source';
|
$html .= ' src="' . esc_url($source['url']) . '"';
|
$html .= ' type="' . esc_attr($source['mime']) . '"';
|
|
// Add media query for desktop if mobile sources exist
|
if (!empty($mobile_sources)) {
|
$html .= ' media="(min-width: 768px)"';
|
}
|
|
$html .= '>';
|
}
|
}
|
|
$html .= '</video>';
|
$html .= '</div></div><div class="inner-wrap"></div></section>';
|
|
return $html;
|
}
|
}
|