<?php
|
namespace JVBase\blocks;
|
|
use JVBase\managers\SEO\render\Thing\CreativeWork\MediaObject\VideoObject;
|
|
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';
|
|
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' : '';
|
$overlay_opacity = $attributes['overlayOpacity'] ?? 0;
|
$content_alignment = $attributes['contentAlignment'] ?? 'center';
|
$min_height = $attributes['minHeight'] ?? 0;
|
//Get date of current post
|
global $post;
|
$date = date('c',strtotime($post->post_date));
|
|
// If no video sources, return empty
|
if (empty($video_sources)) {
|
return '';
|
}
|
|
$video_id = $video_sources[0]['id'] ?? 0;
|
$video_post = $video_id ? get_post($video_id) : null;
|
$title = $video_post->post_title ?? $post->post_title;
|
$description = $video_post->post_content ?? $post->post_excerpt;
|
|
|
|
// Get poster URL
|
$poster_url = $poster_id ? wp_get_attachment_url($poster_id) : '';
|
|
// Build video tag
|
$classes = trim("video-cover {$fade_class} {$css_class}");
|
|
$video = new VideoObject();
|
$video->setName($title);
|
$video->setThumbnailUrl($poster_url);
|
$video->setContentUrl($video_sources[0]['url']);
|
$video->setDescription($description);
|
$video->setUploadDate($date);
|
|
$html = sprintf(
|
'<section class="%s">
|
<script type="application/ld+json">%s</script>
|
<div class="wrap abs edges">
|
<div class="video-container">',
|
esc_attr($classes),
|
json_encode($video->outputSchema())
|
);
|
|
$poster = $poster_url ? sprintf(
|
' poster="%s"',
|
esc_url($poster_url)
|
) : '';
|
|
$html .= sprintf(
|
'<video muted loop playsinline autoplay%s fetch-priority="high">',
|
$poster
|
);
|
|
|
$html .= ' fetch-priority="high">';
|
|
foreach ($video_sources as $source) {
|
if (!empty($source['url']) && !empty($source['mime'])) {
|
$html .= sprintf(
|
'<source data-src="%s" type="%s">',
|
esc_url($source['url']),
|
esc_attr($source['mime'])
|
);
|
}
|
}
|
|
$html .= '</video>';
|
|
$inner_content = $this->extractInnerContent($content);
|
$html .= sprintf(
|
'</div></div><div class="inner-wrap">%s</div></section>',
|
$inner_content
|
);
|
|
return $html;
|
}
|
|
/**
|
* Extract inner content from the saved block content
|
* Removes the wrapper div and returns just the inner blocks HTML
|
*/
|
protected function extractInnerContent(string $content): string
|
{
|
if (empty($content)) {
|
return '';
|
}
|
|
// Remove the placeholder wrapper div
|
$content = preg_replace('/<div[^>]*class="[^"]*video-cover-wrapper-placeholder[^"]*"[^>]*>/', '', $content, 1);
|
$content = preg_replace('/<\/div>\s*$/', '', $content, 1);
|
|
return trim($content);
|
}
|
}
|