From 449aad775fee73629e28eeb0aca1dd2f16994ccd Mon Sep 17 00:00:00 2001 From: Thomas Skerbis Date: Sat, 28 Sep 2024 19:57:05 +0200 Subject: [PATCH] oembedHelper --- lib/video.php | 100 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 68 insertions(+), 32 deletions(-) diff --git a/lib/video.php b/lib/video.php index 138d6ae..d4b5ed8 100644 --- a/lib/video.php +++ b/lib/video.php @@ -1,11 +1,13 @@ source = $source; $this->title = $title; $this->lang = $lang; @@ -27,7 +30,8 @@ private static function getTranslationsFile(): string return rex_path::addon('vidstack', 'lang/translations.php'); } - private function loadTranslations(): void { + private function loadTranslations(): void + { if (empty(self::$translations)) { $file = self::getTranslationsFile(); if (file_exists($file)) { @@ -38,30 +42,35 @@ private function loadTranslations(): void { } } - private function getText(string $key): string { + private function getText(string $key): string + { return self::$translations[$this->lang][$key] ?? "[[{$key}]]"; } - public function setAttributes(array $attributes): void { + public function setAttributes(array $attributes): void + { $this->attributes = $attributes; } - public function setA11yContent(string $description, string $alternativeUrl = ''): void { + public function setA11yContent(string $description, string $alternativeUrl = ''): void + { $alternativeUrl = $alternativeUrl ?: $this->getAlternativeUrl(); - + $this->a11yContent = "
" . "

" . rex_escape($this->getText('video_description')) . ": " . rex_escape($description) . "

" . "
" - . "

" . rex_escape($this->getText('video_alternative_view')) . ": " + . "

" . rex_escape($this->getText('video_alternative_view')) . ": " . rex_escape($this->getText('video_open_alternative_view')) . "

" . "
"; } - public function setThumbnails(string $thumbnailsUrl): void { + public function setThumbnails(string $thumbnailsUrl): void + { $this->thumbnails = $thumbnailsUrl; } - public function addSubtitle(string $src, string $kind, string $label, string $lang, bool $default = false): void { + public function addSubtitle(string $src, string $kind, string $label, string $lang, bool $default = false): void + { $this->subtitles[] = [ 'src' => $src, 'kind' => $kind, @@ -71,18 +80,21 @@ public function addSubtitle(string $src, string $kind, string $label, string $la ]; } - private function getSourceUrl(): string { + private function getSourceUrl(): string + { if (filter_var($this->source, FILTER_VALIDATE_URL)) { return $this->source; } return rex_url::media($this->source); } - private function getAlternativeUrl(): string { + private function getAlternativeUrl(): string + { return $this->getSourceUrl(); } - private function getVideoInfo(): array { + private function getVideoInfo(): array + { $youtubePattern = '%(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=|shorts/)|youtu\.be/)([^"&?/ ]{11})%i'; if (preg_match($youtubePattern, $this->source, $match)) { return ['platform' => 'youtube', 'id' => $match[1]]; @@ -94,32 +106,33 @@ private function getVideoInfo(): array { return ['platform' => 'default', 'id' => '']; } - public function generateFull(): string { + public function generateFull(): string + { $videoInfo = $this->getVideoInfo(); $attributesString = $this->generateAttributesString(); $titleAttr = $this->title ? " title=\"" . rex_escape($this->title) . "\"" : ''; - + $code = "
getText('a11y_video_player')) . "\">"; - + if ($videoInfo['platform'] !== 'default') { $consentTextKey = "consent_text_{$videoInfo['platform']}"; $consentText = $this->getText($consentTextKey); if ($consentText === "[[{$consentTextKey}]]") { $consentText = $this->getText('consent_text_default'); } - + $code .= $this->generateConsentPlaceholder($consentText, $videoInfo['platform'], $videoInfo['id']); } - + $code .= "getText('a11y_video_from')) . " " . rex_escape($videoInfo['platform']) . "\""; + . " aria-label=\"" . rex_escape($this->getText('a11y_video_from')) . " " . rex_escape($videoInfo['platform']) . "\""; } else { $code .= " src=\"" . rex_escape($this->getSourceUrl()) . "\""; } - + $code .= " role=\"application\"" . ($videoInfo['platform'] !== 'default' ? " style=\"display:none;\"" : "") . ">"; $code .= ""; foreach ($this->subtitles as $subtitle) { @@ -128,18 +141,19 @@ public function generateFull(): string { } $code .= "thumbnails ? " thumbnails=\"" . rex_escape($this->thumbnails) . "\"" : "") . ">"; $code .= ""; - + if ($this->a11yContent) { $code .= "
getText('a11y_additional_information')) . "\">" - . $this->a11yContent - . "
"; + . $this->a11yContent + . "
"; } - + $code .= ""; return $code; } - public function generate(): string { + public function generate(): string + { $attributesString = $this->generateAttributesString(); $titleAttr = $this->title ? " title=\"" . rex_escape($this->title) . "\"" : ''; $sourceUrl = $this->getSourceUrl(); @@ -154,18 +168,40 @@ public function generate(): string { return $code; } - private function generateAttributesString(): string { - return array_reduce(array_keys($this->attributes), function($carry, $key) { + private function generateAttributesString(): string + { + return array_reduce(array_keys($this->attributes), function ($carry, $key) { $value = $this->attributes[$key]; return $carry . (is_bool($value) ? ($value ? " " . rex_escape($key) : '') : " " . rex_escape($key) . "=\"" . rex_escape($value) . "\""); }, ''); } - private function generateConsentPlaceholder(string $consentText, string $platform, string $videoId): string { + private function generateConsentPlaceholder(string $consentText, string $platform, string $videoId): string + { $buttonText = $this->getText('Load Video'); return "
" - . "

" . rex_escape($consentText) . "

" - . "" - . "
"; + . "

" . rex_escape($consentText) . "

" + . "" + . ""; + } + public static function videoOembedHelper(): void + { + rex_extension::register('OUTPUT_FILTER', static function (rex_extension_point $ep) { + $content = $ep->getSubject(); + return self::parseOembedTags($content); + }, rex_extension::LATE); + } + + public static function parseOembedTags(string $content): string + { + return preg_replace_callback('/<\/oembed>/is', static function ($match) { + $video = new self($match[1]); + $video->setAttributes([ + 'crossorigin' => '', + 'playsinline' => true, + 'controls' => true + ]); + return $video->generateFull(); + }, $content); } }