Skip to content

Commit cc237b3

Browse files
Issue #63: Add video attributes from original urll and iframe (#64)
1 parent 78da24a commit cc237b3

1 file changed

Lines changed: 141 additions & 9 deletions

File tree

includes/Service/YoutubeVanisher.php

Lines changed: 141 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<?php
22

33
namespace Backdrop\gdpr_cookies\Service;
4+
45
use Backdrop\gdpr_cookies\Entity\ThirdPartyServiceEntityInterface;
56

67
/**
@@ -18,6 +19,19 @@ class YoutubeVanisher extends EmbeddedVideoVanisher {
1819
*/
1920
const YOUTUBE_VIDEO_ID_REGEX = '~^.*(youtu\.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*~i';
2021

22+
/**
23+
* YouTube parameters to preserve when converting iframes.
24+
*/
25+
const PRESERVED_PARAMS = [
26+
'start',
27+
'end',
28+
'autoplay',
29+
'loop',
30+
'mute',
31+
'controls',
32+
'showinfo',
33+
];
34+
2135
/**
2236
* {@inheritdoc}
2337
*/
@@ -26,35 +40,94 @@ protected function getReplacementMarkup(array $data, ThirdPartyServiceEntityInte
2640
$data['height'] = "";
2741
$markup = '<div class="youtube_player" videoID="' . $data['video_id'] . '" ';
2842
$markup .= 'width="' . $data['width'] . '" ';
29-
$markup .= 'style="aspect-ratio:16/9;"></div>';
43+
$markup .= 'style="aspect-ratio:16/9;"';
44+
45+
// Add additional parameters.
46+
if (!empty($data['start'])) {
47+
$markup .= ' start="' . $data['start'] . '"';
48+
}
49+
if (!empty($data['end'])) {
50+
$markup .= ' end="' . $data['end'] . '"';
51+
}
52+
if (!empty($data['autoplay'])) {
53+
$markup .= ' autoplay="' . $data['autoplay'] . '"';
54+
}
55+
if (!empty($data['loop'])) {
56+
$markup .= ' loop="' . $data['loop'] . '"';
57+
}
58+
if (!empty($data['mute'])) {
59+
$markup .= ' mute="' . $data['mute'] . '"';
60+
}
61+
if (!empty($data['controls'])) {
62+
$markup .= ' controls="' . $data['controls'] . '"';
63+
}
64+
if (!empty($data['showinfo'])) {
65+
$markup .= ' showinfo="' . $data['showinfo'] . '"';
66+
}
67+
68+
$markup .= '></div>';
3069
$markup .= filter_xss_admin($entity->getInfo());
3170
return $markup;
3271
}
3372

73+
$replacement = '<div class="youtube_player" videoID="@video_id" width="@width" height="@height"';
74+
75+
// Add additional parameters to template.
76+
if (!empty($data['start'])) {
77+
$replacement .= ' start="@start"';
78+
}
79+
if (!empty($data['end'])) {
80+
$replacement .= ' end="@end"';
81+
}
82+
if (!empty($data['autoplay'])) {
83+
$replacement .= ' autoplay="@autoplay"';
84+
}
85+
if (!empty($data['loop'])) {
86+
$replacement .= ' loop="@loop"';
87+
}
88+
if (!empty($data['mute'])) {
89+
$replacement .= ' mute="@mute"';
90+
}
91+
if (!empty($data['controls'])) {
92+
$replacement .= ' controls="@controls"';
93+
}
94+
if (!empty($data['showinfo'])) {
95+
$replacement .= ' showinfo="@showinfo"';
96+
}
97+
98+
$replacement .= '></div>@info_text';
99+
34100
return str_replace(
35101
[
36102
'@video_id',
37103
'@width',
38104
'@height',
105+
'@start',
106+
'@end',
107+
'@autoplay',
108+
'@loop',
109+
'@mute',
110+
'@controls',
111+
'@showinfo',
39112
'@info_text',
40113
],
41114
[
42115
$data['video_id'],
43116
$data['width'],
44117
$data['height'],
118+
!empty($data['start']) ? $data['start'] : '',
119+
!empty($data['end']) ? $data['end'] : '',
120+
!empty($data['autoplay']) ? $data['autoplay'] : '',
121+
!empty($data['loop']) ? $data['loop'] : '',
122+
!empty($data['mute']) ? $data['mute'] : '',
123+
!empty($data['controls']) ? $data['controls'] : '',
124+
!empty($data['showinfo']) ? $data['showinfo'] : '',
45125
filter_xss_admin($entity->getInfo()),
46126
],
47-
$this->getReplacementMarkupTemplate()
127+
$replacement
48128
);
49129
}
50130

51-
/**
52-
* {@inheritdoc}
53-
*/
54-
protected function getReplacementMarkupTemplate() {
55-
return '<div class="youtube_player" videoID="@video_id" width="@width" height="@height"></div>@info_text';
56-
}
57-
58131
/**
59132
* {@inheritdoc}
60133
*/
@@ -76,9 +149,68 @@ protected function getVideoData($markup) {
76149
$data = parent::getVideoData($markup);
77150
$data['video_id'] = $this->extractVideoId($data['src']);
78151

152+
// Extract additional parameters from URL or iframe attributes.
153+
$data = array_merge($data, $this->getUrlParams($data['src']));
154+
$data = array_merge($data, $this->getIframeAttributes($markup));
155+
79156
return $data;
80157
}
81158

159+
/**
160+
* Extracts URL parameters from the YouTube URL.
161+
*
162+
* @param string $url
163+
* The YouTube URL.
164+
*
165+
* @return array
166+
* Array of parameters.
167+
*/
168+
protected function getUrlParams($url) {
169+
$params = [];
170+
$parsed_url = parse_url($url);
171+
172+
if (isset($parsed_url['query'])) {
173+
parse_str($parsed_url['query'], $query_params);
174+
175+
// Parameters to preserve
176+
foreach (self::PRESERVED_PARAMS as $param) {
177+
if (isset($query_params[$param])) {
178+
$params[$param] = $query_params[$param];
179+
}
180+
}
181+
182+
// Convert 't' to 'start' if exists.
183+
if (isset($query_params['t'])) {
184+
$t_value = preg_replace('/s$/i', '', $query_params['t']);
185+
$params['start'] = $t_value;
186+
}
187+
}
188+
189+
return $params;
190+
}
191+
192+
/**
193+
* Extracts attributes from the iframe element.
194+
*
195+
* @param string $markup
196+
* The iframe markup.
197+
*
198+
* @return array
199+
* Array of attributes.
200+
*/
201+
protected function getIframeAttributes($markup) {
202+
$attributes = [];
203+
204+
foreach (self::PRESERVED_PARAMS as $attribute) {
205+
$pattern = '/' . $attribute . '=["\']([^"\']*)["\']|' . $attribute . '=([^\s>]*)/i';
206+
if (preg_match($pattern, $markup, $matches)) {
207+
$attributes[$attribute] = !empty($matches[1]) ? $matches[1] : $matches[2];
208+
}
209+
}
210+
211+
return $attributes;
212+
}
213+
82214
/**
83215
* Extracts the video id.
84216
*

0 commit comments

Comments
 (0)