PluginProbe ʕ •ᴥ•ʔ
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more / 3.6.8
EmbedPress – PDF Embedder, Embed PDF viewer, YouTube Videos, 3D FlipBook, Social feeds & more v3.6.8
4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 trunk 1.0.0 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 2.0.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.2.0 2.2.1 2.2.2 2.3.0 2.3.1 2.3.2 2.3.3 2.4.0 2.4.1 2.5.0 2.5.1 2.5.2 2.5.3 2.5.4 2.5.5 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.0.3 3.0.4 3.1.0 3.1.1 3.1.2 3.1.3 3.2.0 3.2.1 3.3.0 3.3.1 3.3.2 3.3.3 3.3.4 3.3.5 3.3.6 3.3.7 3.4.0 3.4.1 3.4.2 3.4.3 3.5.0 3.5.1 3.5.2 3.5.3 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.6.8 3.7.0 3.7.1 3.7.2 3.7.3 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.9.0 3.9.1 3.9.10 3.9.11 3.9.12 3.9.13 3.9.14 3.9.15 3.9.16 3.9.17 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9 4.0.0 4.0.1 4.0.10 4.0.11 4.0.12 4.0.13 4.0.14 4.0.2 4.0.3 4.0.4 4.0.5 4.0.6 4.0.7 4.0.8 4.0.9 4.1.0 4.1.1 4.1.10 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 4.1.7 4.1.8 4.1.9 4.2.0 4.2.1 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.8 4.2.9 4.3.0 4.3.1 4.4.0 4.4.1 4.4.10 4.4.11 4.4.2 4.4.3 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5.0 4.5.1
embedpress / EmbedPress / Providers / Youtube.php
embedpress / EmbedPress / Providers Last commit date
Boomplay.php 5 years ago Giphy.php 5 years ago GoogleDocs.php 5 years ago GoogleMaps.php 3 years ago OpenSea.php 3 years ago Twitch.php 5 years ago Youtube.php 3 years ago index.html 7 years ago
Youtube.php
846 lines
1 <?php
2
3 /**
4 * Youtube.php
5 *
6 * @package Embera
7 * @author Michael Pratt <yo@michael-pratt.com>
8 * @link http://www.michael-pratt.com/
9 *
10 * For the full copyright and license information, please view the LICENSE
11 * file that was distributed with this source code.
12 */
13
14 namespace EmbedPress\Providers;
15
16 use Embera\Provider\ProviderAdapter;
17 use Embera\Provider\ProviderInterface;
18 use Embera\Url;
19
20 /**
21 * youtube.com Provider
22 * @link https://youtube.com
23 * @link https://youtube-eng.googleblog.com/2009/10/oembed-support_9.html
24 */
25
26
27 class Youtube extends ProviderAdapter implements ProviderInterface {
28 /** inline {@inheritdoc} */
29 protected $shouldSendRequest = false;
30 public static $curltimeout = 30;
31 /** inline {@inheritdoc} */
32 protected $endpoint = 'https://www.youtube.com/oembed?format=json&scheme=https';
33 protected static $channel_endpoint = 'https://www.googleapis.com/youtube/v3/';
34 /** @var array Array with allowed params for the current Provider */
35 protected $allowedParams = [ 'maxwidth', 'maxheight', 'pagesize', 'thumbnail', 'gallery', 'hideprivate', 'columns', 'ispagination', 'gapbetweenvideos' ];
36
37 /** inline {@inheritdoc} */
38 protected static $hosts = [
39 'm.youtube.com', 'youtube.com', 'youtu.be',
40 ];
41
42 /** inline {@inheritdoc} */
43 protected $httpsSupport = true;
44
45 public function getAllowedParams(){
46 return $this->allowedParams;
47 }
48
49 /** inline {@inheritdoc} */
50 public function validateUrl(Url $url) {
51 return (bool) (preg_match('~\/channel\/|\/c\/|\/user\/|\/@\w+|(?:https?:\/\/)?(?:www\.)?(?:youtube.com\/)(\w+)[^?\/]*$~i', (string) $url));
52 }
53
54 /** inline {@inheritdoc} */
55 public function normalizeUrl(Url $url) {
56 return $url;
57 }
58
59 public function isChannel($url = null) {
60 if (empty($url)) {
61 $url = $this->url;
62 }
63 $channel = $this->getChannel($url);
64 return !empty($channel['id']);
65 }
66
67 public function getChannel($url = null) {
68 if (empty($url)) {
69 $url = $this->url;
70 }
71 preg_match('~\/(channel|c|user)\/(.+)~i', (string) $url, $matches);
72 if(empty($matches[1])){
73 preg_match('~(?:https?:\/\/)?(?:www\.)?(?:youtube.com\/)(\w+)[^?\/]*$~i', (string) $url, $matches);
74 if(!empty($matches[1])){
75 return [
76 "type" => 'user',
77 "id" => $matches[1],
78 ];
79 }
80 }
81 if(empty($matches[1])){
82 preg_match('~\/(@)(\w+)~i', (string) $url, $matches);
83 if(!empty($matches[1])){
84 return [
85 "type" => 'user',
86 "id" => $matches[2],
87 ];
88 }
89 }
90 return [
91 "type" => isset($matches[1]) ? $matches[1] : '',
92 "id" => isset($matches[2]) ? $matches[2] : '',
93 ];
94 }
95
96 /** inline {@inheritdoc} */
97 public function getEndpoint() {
98 if ($this->isChannel()) {
99 $apiEndpoint = 'https://www.googleapis.com/youtube/v3/channels';
100 return $apiEndpoint;
101 }
102 return (string) $this->endpoint;
103 }
104
105 protected static function get_api_key() {
106 $settings = (array) get_option(EMBEDPRESS_PLG_NAME . ':youtube', []);
107 return !empty($settings['api_key']) ? $settings['api_key'] : '';
108 }
109
110 protected static function get_pagesize() {
111 $settings = (array) get_option(EMBEDPRESS_PLG_NAME . ':youtube', []);
112 return !empty($settings['pagesize']) ? $settings['pagesize'] : '';
113 }
114
115 /** inline {@inheritdoc} */
116 public function getParams() {
117 $params = parent::getParams();
118 if ($this->isChannel() && self::get_api_key()) {
119 $channel = $this->getChannel();
120 $params['part'] = 'contentDetails,snippet';
121 $params['key'] = self::get_api_key();
122 if ($channel['type'] == 'c') {
123 $params['forUsername'] = $channel['id'];
124 } else {
125 $params['id'] = $channel['id'];
126 }
127 unset($params['url']);
128 }
129 return $params;
130 }
131
132 /**
133 * Builds a valid Oembed query string based on the given parameters,
134 * Since this method uses the http_build_query function, there is no
135 * need to pass urlencoded parameters, http_build_query already does
136 * this for us.
137 *
138 * @param string $endpoint The Url to the Oembed endpoint
139 * @param array $params Parameters for the query string
140 * @return string
141 */
142
143 protected function constructUrl($endpoint, array $params = array())
144 {
145 $endpoint = self::$channel_endpoint . $endpoint;
146
147 return $endpoint . ((strpos($endpoint, '?') === false) ? '?' : '&') . http_build_query(array_filter($params));
148 }
149
150 public function getStaticResponse() {
151 $results = [
152 "title" => "",
153 "type" => "video",
154 'provider_name' => $this->getProviderName(),
155 "provider_url" => "https://www.youtube.com/",
156 'html' => '',
157 ];
158 if($this->isChannel()){
159 $channel = $this->getChannelGallery();
160 $results = array_merge($results, $channel);
161 }
162 return $results;
163 }
164
165 public function getChannelPlaylist(){
166 $result = [
167 "playlistID" => '',
168 "title" => '',
169 ];
170 $channel = $this->getChannel();
171 $channel_url = $this->constructUrl('channels', $this->getParams());
172 $transient_key = 'ep_embed_youtube_channel_playlist_id_' . md5($channel_url);
173 $jsonResult = get_transient($transient_key);
174
175 if(!empty($jsonResult)){
176 return $jsonResult;
177 }
178
179 if($channel['type'] == 'user' || $channel['type'] == 'c'){
180 $this->getChannelIDbyUsername();
181 $channel_url = $this->constructUrl('channels', $this->getParams());
182 }
183
184 if (empty(self::get_api_key())) {
185 $result['error'] = true;
186 $result['html'] = self::get_api_key_error_message();
187 return $result;
188 }
189
190 $apiResult = wp_remote_get($channel_url, array('timeout' => self::$curltimeout));
191 if (is_wp_error($apiResult)) {
192 $result['error'] = true;
193 $result['html'] = self::clean_api_error_html($apiResult->get_error_message(), true);
194 set_transient($transient_key, $result, 10);
195 return $result;
196 }
197 $jsonResult = json_decode($apiResult['body']);
198
199
200 if (isset($jsonResult->error)) {
201 $result['error'] = true;
202 if (isset($jsonResult->error->message)) {
203 $result['html'] = self::clean_api_error_html($jsonResult->error->message, true);
204 }
205 else{
206 $result['html'] = self::clean_api_error_html(__('Sorry, there may be an issue with your YouTube API key.', 'embedpress'));
207 }
208 set_transient($transient_key, $result, MINUTE_IN_SECONDS);
209 return $result;
210 }
211 elseif(!empty($jsonResult->items[0]->contentDetails->relatedPlaylists->uploads)){
212 $result['playlistID'] = $jsonResult->items[0]->contentDetails->relatedPlaylists->uploads;
213 $result['title'] = isset($jsonResult->items[0]->snippet->title) ? $jsonResult->items[0]->snippet->title : '';
214 set_transient($transient_key, $result, DAY_IN_SECONDS);
215 }
216
217 return $result;
218 }
219
220 public function getChannelIDbyUsername(){
221 $url = $this->getUrl();
222 $apiResult = wp_remote_get($url, array('timeout' => self::$curltimeout));
223
224 if (!is_wp_error($apiResult)) {
225 $channel_html = $apiResult['body'];
226 preg_match("/<meta\s+itemprop=[\"']channelId[\"']\s+content=[\"'](.*?)[\"']\/?>/", $channel_html, $matches);
227 if(!empty($matches[1])){
228 $url = "https://www.youtube.com/channel/{$matches[1]}";
229 $this->url = $this->normalizeUrl(new Url($url));
230 }
231 }
232 }
233
234 /** inline {@inheritdoc} */
235 public function getChannelGallery() {
236 $response = [];
237 $channel = $this->getChannelPlaylist();
238 if(!empty($channel['error'])){
239 return $channel;
240 }
241 if (!empty($channel["playlistID"])) {
242 $params = $this->getParams();
243 $the_playlist_id = $channel["playlistID"];
244 $rel = 'https://www.youtube.com/embed?listType=playlist&list=' . esc_attr($the_playlist_id);
245 $title = $channel['title'];
246 $main_iframe = "";
247 $gallery_args = [
248 'playlistId' => $the_playlist_id,
249 ];
250 if(!empty($params['pagesize'])){
251 $gallery_args['pagesize'] = $params['pagesize'];
252 }
253 $gallery = self::get_gallery_page($gallery_args);
254
255 if (!empty($gallery->first_vid)) {
256 $rel = "https://www.youtube.com/embed/{$gallery->first_vid}?feature=oembed";
257 $main_iframe = "<div class='ep-first-video'><iframe width='{$params['maxwidth']}' height='{$params['maxheight']}' src='$rel' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture' allowfullscreen title='{$title}'></iframe></div>";
258 }
259 if($gallery->html){
260 $styles = self::styles($params, $this->getUrl());
261 return [
262 "title" => $title,
263 "html" => "<div class='ep-player-wrap'>$main_iframe {$gallery->html} $styles</div>",
264 ];
265 }
266 }
267 elseif ($this->isChannel() && empty(self::get_api_key()) && current_user_can('manage_options')) {
268 return [
269 "html" => "<div class='ep-player-wrap'>" . __('Please enter your YouTube API key to embed YouTube Channel.', 'embedpress') . "</div>",
270 ];
271 }
272
273 return $response;
274 }
275
276 /**
277 * Undocumented function
278 *
279 * @param array $options
280 * @return object
281 */
282 public static function get_gallery_page($options) {
283 $nextPageToken = '';
284 $prevPageToken = '';
285 $gallobj = new \stdClass();
286 $options = wp_parse_args($options, [
287 'playlistId' => '',
288 'pageToken' => '',
289 'pagesize' => self::get_pagesize() ? self::get_pagesize() : 6,
290 'currentpage' => '',
291 'columns' => 3,
292 'thumbnail' => 'medium',
293 'gallery' => true,
294 'autonext' => true,
295 'thumbplay' => true,
296 'apiKey' => self::get_api_key(),
297 'hideprivate' => '',
298 ]);
299 $options['pagesize'] = $options['pagesize'] > 50 ? 50 : $options['pagesize'];
300 $options['pagesize'] = $options['pagesize'] < 1 ? 1 : $options['pagesize'];
301
302 if (empty($options['apiKey'])) {
303 $gallobj->html = self::get_api_key_error_message();
304 return $gallobj;
305 }
306
307 $apiEndpoint = 'https://www.googleapis.com/youtube/v3/playlistItems?part=snippet,status&playlistId=' . $options['playlistId']
308 . '&maxResults=' . $options['pagesize']
309 . '&key=' . $options['apiKey'];
310 if ($options['pageToken'] != null) {
311 $apiEndpoint .= '&pageToken=' . $options['pageToken'];
312 }
313
314 $transient_key = 'ep_embed_youtube_channel_' . md5($apiEndpoint);
315 $gallobj->transient_key = $transient_key;
316 $jsonResult = get_transient($transient_key);
317 if (empty($jsonResult)) {
318 $apiResult = wp_remote_get($apiEndpoint, array('timeout' => self::$curltimeout));
319 if (is_wp_error($apiResult)) {
320 $gallobj->html = self::clean_api_error_html($apiResult->get_error_message(), true);
321 return $gallobj;
322 }
323 $jsonResult = json_decode($apiResult['body']);
324 if (empty($jsonResult->error)) {
325 set_transient($transient_key, $jsonResult, MINUTE_IN_SECONDS * 20);
326 }
327 else{
328 set_transient($transient_key, $jsonResult, 10);
329 }
330 }
331
332
333 if (isset($jsonResult->error)) {
334 if(!empty($jsonResult->error->errors[0]->reason) && $jsonResult->error->errors[0]->reason == 'playlistNotFound'){
335 $gallobj->html = self::clean_api_error_html(__('There is nothing on the playlist.', 'embedpress'));
336 return $gallobj;
337 }
338 if (isset($jsonResult->error->message)) {
339 $gallobj->html = self::clean_api_error_html($jsonResult->error->message);
340 return $gallobj;
341 }
342 $gallobj->html = self::clean_api_error_html(__('Sorry, there may be an issue with your YouTube API key.', 'embedpress'));
343 return $gallobj;
344 }
345
346
347
348 $resultsPerPage = $jsonResult->pageInfo->resultsPerPage;
349 $totalResults = $jsonResult->pageInfo->totalResults;
350 $totalPages = ceil($totalResults / $resultsPerPage);
351 if (isset($jsonResult->nextPageToken)) {
352 $nextPageToken = $jsonResult->nextPageToken;
353 }
354
355 if (isset($jsonResult->prevPageToken)) {
356 $prevPageToken = $jsonResult->prevPageToken;
357 }
358
359
360 if (!empty($jsonResult->items) && is_array($jsonResult->items)) :
361 if($options['gallery'] === "false"){
362 $gallobj->html = "";
363 if(count($jsonResult->items) === 1){
364 $gallobj->first_vid = self::get_id($jsonResult->items[0]);
365 }
366 return $gallobj;
367 }
368
369 if(count($jsonResult->items) === 1 && empty($nextPageToken) && empty($prevPageToken)){
370 $gallobj->first_vid = self::get_id($jsonResult->items[0]);
371 $gallobj->html = "";
372 return $gallobj;
373 }
374
375 if (strpos($options['playlistId'], 'UU') === 0) {
376 // sort only channels
377 usort($jsonResult->items, array(get_class(), 'compare_vid_date')); // sorts in place
378 }
379
380 ob_start();
381 ?>
382 <div class="ep-youtube__content__block" data-unique-id="<?php echo wp_rand(); ?>">
383 <div class="youtube__content__body">
384 <div class="content__wrap">
385 <?php foreach ($jsonResult->items as $item) : ?>
386 <?php
387 $privacyStatus = isset($item->status->privacyStatus) ? $item->status->privacyStatus : null;
388 $thumbnail = self::get_thumbnail_url($item, $options['thumbnail'], $privacyStatus);
389 $vid = self::get_id($item);
390 if (empty($gallobj->first_vid)) {
391 $gallobj->first_vid = $vid;
392 }
393 if ($privacyStatus == 'private' && $options['hideprivate']) {
394 continue;
395 }
396 ?>
397 <div class="item" data-vid="<?php echo $vid; ?>">
398 <div class="thumb" style="background: <?php echo "url({$thumbnail}) no-repeat center"; ?>">
399 <div class="play-icon">
400 <img src="<?php echo EMBEDPRESS_URL_ASSETS . 'images/youtube/youtube-play.png'; ?>" alt="">
401 </div>
402 </div>
403 <div class="body">
404 <p><?php echo $item->snippet->title; ?></p>
405 </div>
406 </div>
407
408 <?php endforeach; ?>
409 <div class="item" style="height: 0"></div>
410 </div>
411
412
413 <?php if ($totalPages > 1) : ?>
414 <div class="ep-youtube__content__pagination <?php echo (empty($prevPageToken) && empty($nextPageToken)) ? ' hide ' : ''; ?>">
415 <div
416 class="ep-prev" <?php echo empty($prevPageToken) ? ' style="display:none" ' : ''; ?>
417 data-playlistid="<?php echo esc_attr($options['playlistId']) ?>"
418 data-pagetoken="<?php echo esc_attr($prevPageToken) ?>"
419 data-pagesize="<?php echo intval($options['pagesize']) ?>"
420 >
421 <span><?php _e("Prev", "embedpress"); ?></span>
422 </div>
423 <div class="is_desktop_device ep-page-numbers <?php echo $totalPages > 1 ? '' : 'hide'; ?>">
424 <?php
425
426 $numOfPages = $totalPages;
427 $renderedEllipses = false;
428
429 $currentPage = !empty($options['currentpage'])?$options['currentpage'] : 1;
430
431 for($i = 1; $i<=$numOfPages; $i++)
432 {
433 //render pages 1 - 3
434 if($i < 4) {
435 //render link
436 $is_current = $i == (int)$currentPage? "active__current_page" : "";
437
438 echo wp_kses_post("<span class='page-number $is_current' data-page='$i'>$i</span>");
439
440 }
441
442 //render current page number
443 else if($i == (int)$currentPage) {
444 //render link
445 echo wp_kses_post('<span class="page-number active__current_page" data-page="'.$i.'">'.$i.'</span>');
446 //reset ellipses
447 $renderedEllipses = false;
448 }
449
450 //last page number
451 else if ($i >= $numOfPages - 1) {
452 //render link
453 echo wp_kses_post('<span class="page-number" data-page="'.$i.'">'.$i.'</span>');
454 }
455
456 //make sure you only do this once per ellipses group
457 else {
458 if (!$renderedEllipses){
459 print("...");
460 $renderedEllipses = true;
461 }
462 }
463 }
464 ?>
465
466 </div>
467
468 <div class="is_mobile_device ep-page-numbers <?php echo $totalPages > 1 ? '' : 'hide'; ?>">
469 <?php
470
471 $numOfPages = $totalPages;
472 $renderedEllipses = false;
473
474 $currentPage = !empty($options['currentpage'])?$options['currentpage'] : 1;
475
476 for($i = 1; $i<=$numOfPages; $i++)
477 {
478
479 //render current page number
480 if($i == (int)$currentPage) {
481 //render link
482 echo wp_kses_post('<span class="page-number-mobile" data-page="'.$i.'">'.$i.'</span>');
483 //reset ellipses
484 $renderedEllipses = false;
485 }
486
487 //last page number
488 else if ($i >= $numOfPages ) {
489 //render link
490 echo wp_kses_post('...<span class="page-number-mobile" data-page="'.$i.'">'.$i.'</span>');
491 }
492 }
493 ?>
494
495 </div>
496
497
498 <div
499 class="ep-next " <?php echo empty($nextPageToken) ? ' style="display:none" ' : ''; ?>
500 data-playlistid="<?php echo esc_attr($options['playlistId']) ?>"
501 data-pagetoken="<?php echo esc_attr($nextPageToken) ?>"
502 data-pagesize="<?php echo intval($options['pagesize']) ?>"
503 >
504 <span><?php _e("Next ", "embedpress"); ?> </span>
505 </div>
506 </div>
507 <?php endif; ?>
508
509 <div class="ep-loader-wrap">
510 <div class="ep-loader"><img alt="loading" src="<?php echo EMBEDPRESS_URL_ASSETS . 'images/youtube/spin.gif'; ?>"></div>
511 </div>
512
513 </div>
514 </div>
515 <?php
516 $gallobj->html = ob_get_clean();
517 else:
518 $gallobj->html = self::clean_api_error_html(__("There is nothing on the playlist.", 'embedpress'));
519 endif;
520
521 return $gallobj;
522 }
523
524 public static function get_api_key_error_message(){
525 return '<div>' . sprintf(__("EmbedPress: Please enter your YouTube API key at <a class='ep-link' href='%s' target='_blank' style='color: #5b4e96; text-decoration: none'>EmbedPress > Platforms > YouTube</a> to embed YouTube Channel.", "embedpress"), admin_url('?page=embedpress&page_type=youtube#api_key')) . '</div>';
526 }
527
528 public static function get_id($item){
529 $vid = isset($item->snippet->resourceId->videoId) ? $item->snippet->resourceId->videoId : null;
530 $vid = $vid ? $vid : (isset($item->id->videoId) ? $item->id->videoId : null);
531 $vid = $vid ? $vid : (isset($item->id) ? $item->id : null);
532 return $vid;
533 }
534 public static function get_thumbnail_url($item, $quality, $privacyStatus) {
535 $url = "";
536 if ($privacyStatus == 'private') {
537 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/private.png';
538 } elseif (isset($item->snippet->thumbnails->{$quality}->url)) {
539 $url = $item->snippet->thumbnails->{$quality}->url;
540 } elseif (isset($item->snippet->thumbnails->medium->url)) {
541 $url = $item->snippet->thumbnails->medium->url;
542 } elseif (isset($item->snippet->thumbnails->default->url)) {
543 $url = $item->snippet->thumbnails->default->url;
544 } elseif (isset($item->snippet->thumbnails->high->url)) {
545 $url = $item->snippet->thumbnails->high->url;
546 } else {
547 $url = EMBEDPRESS_URL_ASSETS . 'images/youtube/deleted-video-thumb.png';
548 }
549 return $url;
550 }
551
552 public static function compare_vid_date($a, $b) {
553 if ($a->snippet->publishedAt == $b->snippet->publishedAt) {
554 return 0;
555 }
556 return ($a->snippet->publishedAt > $b->snippet->publishedAt) ? -1 : 1;
557 }
558
559 public static function clean_api_error($raw_message) {
560 return htmlspecialchars(strip_tags(preg_replace('@&key=[^& ]+@i', '&key=*******', $raw_message)));
561 }
562
563 public static function clean_api_error_html($raw_message) {
564 $clean_html = '';
565 if ((defined('REST_REQUEST') && REST_REQUEST) || current_user_can('manage_options')) {
566 $clean_html = '<div>' . __('EmbedPress: ', 'embedpress') . self::clean_api_error($raw_message) . '</div>';
567 }
568 return $clean_html;
569 }
570
571 /** inline {@inheritdoc} */
572 public function getFakeResponse() {
573 preg_match('~v=([a-z0-9_\-]+)~i', (string) $this->url, $matches);
574
575 $embedUrl = 'https://www.youtube.com/embed/' . $matches['1'] . '?feature=oembed';
576
577 $attr = [];
578 $attr[] = 'width="{width}"';
579 $attr[] = 'height="{height}"';
580 $attr[] = 'src="' . $embedUrl . '"';
581 $attr[] = 'frameborder="0"';
582 $attr[] = 'allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"';
583 $attr[] = 'allowfullscreen';
584
585 return [
586 'type' => 'video',
587 'provider_name' => 'Youtube',
588 'provider_url' => 'https://www.youtube.com',
589 'title' => 'Unknown title',
590 'html' => '<iframe ' . implode(' ', $attr) . '></iframe>',
591 ];
592 }
593
594 // public static $num = 0;
595
596
597
598 public static $x = 0;
599
600 public static function styles($params, $url){
601
602 $uniqid = '.ose-youtube.ose-uid-'.md5($url);
603
604 ob_start();
605 ?>
606 <style>
607 html {
608 scroll-behavior: smooth;
609 }
610 .ep-player-wrap .hide {
611 display: none;
612 }
613
614 .ep-gdrp-content {
615 background: #222;
616 padding: 50px 30px;
617 color: #fff;
618 }
619
620 .ep-gdrp-content a {
621 color: #fff;
622 }
623
624 .ep-youtube__content__pagination {
625 display: flex;
626 justify-content: center;
627 align-items: center;
628 margin-top: 30px;
629 gap: 10px;
630 }
631 .ep-loader-wrap {
632 margin-top: 30px;
633 display: flex;
634 justify-content: center;
635 }
636
637 .ep-youtube__content__pagination .ep-prev,
638 .ep-youtube__content__pagination .ep-next {
639 cursor: pointer;
640 border: 1px solid rgba(0, 0, 0, .1);
641 border-radius: 30px;
642 padding: 0 20px;
643 height: 40px;
644 transition: .3s;
645 display: flex;
646 align-items: center;
647 }
648 .ep-youtube__content__pagination .ep-prev:hover,
649 .ep-youtube__content__pagination .ep-next:hover{
650 background-color: #5B4E96;
651 color: #fff;
652 }
653 .ep-youtube__content__pagination .ep-page-numbers {
654 display: flex;
655 align-items: center;
656 gap: 10px;
657 flex-wrap: wrap;
658 }
659 .ep-youtube__content__pagination .ep-page-numbers > span {
660 border: 1px solid rgba(0, 0, 0, .1);
661 border-radius: 30px;
662 display: inline-block;
663 width: 45px;
664 height: 45px;
665 display: flex;
666 align-items: center;
667 justify-content: center;
668 }
669 .active__current_page{
670 background: #5B4E96;
671 color: #fff;
672 }
673
674 .ep-youtube__content__block .youtube__content__body .content__wrap {
675 margin-top: 30px;
676 display: grid;
677 grid-template-columns:repeat(auto-fit, minmax(250px, 1fr));
678 gap: 30px;
679 }
680
681 .ep-youtube__content__block .item {
682 cursor: pointer;
683 white-space: initial;
684 }
685
686 .ep-youtube__content__block .item:hover .thumb .play-icon {
687 opacity: 1;
688 top: 50%;
689 }
690
691 .ep-youtube__content__block .item:hover .thumb:after {
692 opacity: .4;
693 z-index: 0;
694 }
695
696 .ep-youtube__content__block .thumb {
697 padding-top: 56.25%;
698 margin-bottom: 5px;
699 position: relative;
700 background: #222;
701 background-size: contain !important;
702 }
703
704 .ep-youtube__content__block .thumb:after {
705 position: absolute;
706 top: 0;
707 left: 0;
708 height: 100%;
709 width: 100%;
710 content: '';
711 background: #000;
712 opacity: 0;
713 transition: opacity .3s ease;
714 }
715
716 .ep-youtube__content__block .thumb:before {
717 position: absolute;
718 top: 0;
719 left: 0;
720 height: 100%;
721 width: 100%;
722 content: '';
723 background: #222;
724 z-index: -1;
725 }
726
727 .ep-youtube__content__block .thumb img {
728 width: 100%;
729 height: 100%;
730 object-fit: cover;
731 }
732
733 .ep-youtube__content__block .thumb .play-icon {
734 width: 50px;
735 height: auto;
736 position: absolute;
737 top: 40%;
738 left: 50%;
739 transform: translate(-50%, -50%);
740 opacity: 0;
741 transition: all .3s ease;
742 z-index: 2;
743 }
744
745 .ep-youtube__content__block .thumb .play-icon img {
746 width: 100;
747 }
748
749 .ep-youtube__content__block .body p {
750 margin-bottom: 0;
751 font-size: 15px;
752 text-align: left;
753 line-height: 1.5;
754 font-weight: 400;
755 }
756 .ep-youtube__content__block.loading .ep-youtube__content__pagination {
757 display: none;
758 }
759
760 .ep-youtube__content__block .ep-loader {
761 display: none;
762 }
763
764 .ep-youtube__content__block.loading .ep-loader {
765 display: block;
766 }
767 .ep-loader img {
768 width: 20px;
769 }
770 .is_mobile_device{
771 display: none!important;
772 }
773
774
775 .is_mobile_devic.ep-page-numbers {
776 gap: 5px;
777 }
778
779 @media only screen and (max-width: 480px) {
780 .is_desktop_device{
781 display: none!important;
782 }
783 .ep-youtube__content__pagination .ep-page-numbers > span {
784 width: 35px;
785 height: 35px;
786 }
787 .ep-youtube__content__pagination .ep-prev, .ep-youtube__content__pagination .ep-next{
788 height: 35px;
789 }
790 .is_mobile_device{
791 display: flex!important;;
792 }
793 .ep-youtube__content__pagination .ep-page-numbers {
794 gap: 5px;
795 }
796 }
797 <?php
798 $attributes_data = $params;
799
800 $is_pagination = 'flex';
801
802 $gap = '30';
803 $columns = '';
804
805 if (isset($attributes_data['ispagination']) && $attributes_data['ispagination']) {
806 $is_pagination = 'none';
807 }
808 if(isset($attributes_data['gapbetweenvideos'])){
809 $gap = $attributes_data['gapbetweenvideos'];
810 }
811 if(isset($attributes_data['columns'])){
812 $columns = $attributes_data['columns'];
813 }
814
815
816 if(!empty($columns) && (int) $columns > 0){
817 $repeatCol = 'repeat(auto-fit, minmax('.esc_html('calc('.(100 / (int) $columns).'% - '.$gap.'px)').', 1fr))';
818 }
819 else{
820 $repeatCol = 'repeat(auto-fit, minmax(calc(250px - '.$gap.'px), 1fr))';
821 }
822
823 ?>
824 <?php echo esc_attr($uniqid); ?> .ep-youtube__content__block .youtube__content__body .content__wrap {
825 gap: <?php echo esc_html($gap); ?>px !important;
826 margin-top: <?php echo esc_html($gap); ?>px !important;
827 grid-template-columns: <?php echo $repeatCol; ?>;
828 }
829 <?php echo esc_attr($uniqid); ?> .ep-youtube__content__block .ep-youtube__content__pagination {
830 display: <?php echo esc_html($is_pagination); ?>!important;
831 }
832
833 <?php
834 if($is_pagination){
835 echo esc_attr($uniqid) ?> {
836 height: 100%!important;
837 }
838 <?php
839 }
840 ?>
841 </style>
842 <?php
843 return ob_get_clean();
844 }
845 }
846