From 8ec8bc04518f21b13416595307bf480dfd5b2503 Mon Sep 17 00:00:00 2001
From: Stefan Galinski <stefan@sgalinski.de>
Date: Thu, 24 Nov 2022 18:57:23 +0100
Subject: [PATCH] [FEATURE] Render videos like requested from Vimeo, Always
 show API debug if wanted, Add missing allow rules to the iframe

---
 Classes/Controller/VimeoController.php        | 34 ++++++-------------
 Classes/Service/VimeoService.php              |  6 ++--
 Resources/Private/Templates/Vimeo/Index.html  | 10 +++---
 .../Public/JavaScript/sgVimeoLightbox.js      | 13 ++++---
 4 files changed, 25 insertions(+), 38 deletions(-)

diff --git a/Classes/Controller/VimeoController.php b/Classes/Controller/VimeoController.php
index 51cdaa3..d08f828 100644
--- a/Classes/Controller/VimeoController.php
+++ b/Classes/Controller/VimeoController.php
@@ -1,7 +1,5 @@
 <?php
 
-namespace SGalinski\SgVimeo\Controller;
-
 /***************************************************************
  *  Copyright notice
  *  (c) sgalinski Internet Services (https://www.sgalinski.de)
@@ -20,7 +18,8 @@ namespace SGalinski\SgVimeo\Controller;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
-use http\Exception\RuntimeException;
+namespace SGalinski\SgVimeo\Controller;
+
 use SGalinski\SgVimeo\Service\VimeoService;
 use TYPO3\CMS\Core\Imaging\ImageManipulation\CropVariantCollection;
 use TYPO3\CMS\Core\Resource\FileReference;
@@ -45,25 +44,16 @@ class VimeoController extends ActionController {
 		$clientId = $this->settings['clientId'];
 		$clientSecret = $this->settings['clientSecret'];
 		$personalAccessToken = $this->settings['personalAccessToken'];
-
 		if (trim($clientId) === '' || trim($clientSecret) === '') {
 			$this->view->assign('error', 'Please configure a client id and a client secret for sg_vimeo.');
 			return;
 		}
 
-		$filterIds = explode(',', $filterIds);
-		foreach ($filterIds as &$filterId) {
-			$filterId = trim($filterId, " ");
-		}
-
+		$filterIds = GeneralUtility::trimExplode(',', $filterIds);
 		$maxResultsWithFilters = (string) ($maxResults + count($filterIds));
 
-		/** @var VimeoService $vimeoService */
 		$vimeoService = GeneralUtility::makeInstance(
-			VimeoService::class,
-			$clientId,
-			$clientSecret,
-			$personalAccessToken
+			VimeoService::class, $clientId, $clientSecret, $personalAccessToken
 		);
 		try {
 			$response = $vimeoService->getVimeoData($id, $maxResultsWithFilters);
@@ -84,7 +74,6 @@ class VimeoController extends ActionController {
 
 			// Fix the array indexes from previous filtering
 			$response['items'] = array_values($response['items']);
-
 			while (count($response['items']) > $maxResults) {
 				array_pop($response['items']);
 			}
@@ -99,21 +88,20 @@ class VimeoController extends ActionController {
 				if (!((int) $endOfLink === $item['videoId'])) {
 					$item['link'] = strstr($item['link'], '.com/', TRUE) . '.com/' . $item['videoId'];
 				}
+
+				if (isset($item['embed']['html'])) {
+					$embedLink = [];
+					preg_match('/src="([^"]+)"/is', $item['embed']['html'], $embedLink);
+					$item['embedLink'] = html_entity_decode($embedLink[1]);
+				}
 			}
 			unset($item);
 		}
 
-		$showApiResult = (int) ($this->settings['showApiResult'] ?? 1);
-		$context = \TYPO3\CMS\Core\Core\Environment::getContext();
-		// disable API debug output in production context
-		if ($context->isProduction()) {
-			$showApiResult = 0;
-		}
-
 		$this->view->assignMultiple(
 			[
 				'response' => $response,
-				'showApiResult' => $showApiResult,
+				'showApiResult' => (int) ($this->settings['showApiResult'] ?? 1),
 				'showTitle' => (int) ($this->settings['showTitle'] ?? 1),
 				'showDescription' => (int) ($this->settings['showDescription'] ?? 1),
 			]
diff --git a/Classes/Service/VimeoService.php b/Classes/Service/VimeoService.php
index 589cbcb..9278d93 100644
--- a/Classes/Service/VimeoService.php
+++ b/Classes/Service/VimeoService.php
@@ -124,7 +124,7 @@ class VimeoService implements LoggerAwareInterface {
 			$response['items'] = $this->addVideoIdsToResponse($this->getChannelVideos($channelId));
 			$response['kind'] = 'channel';
 		} else {
-			$response['items'] = $this->addVideoIdsToResponse($this->getVideo($vimeoId));
+			$response['items'] = $this->addVideoIdsToResponse($this->getVideo((int) $vimeoId));
 			$response['kind'] = 'video';
 		}
 
@@ -227,10 +227,10 @@ class VimeoService implements LoggerAwareInterface {
 	 * Returns a single video for the given $videoId
 	 *
 	 * @see https://developer.vimeo.com/api/reference/videos#get_video
-	 * @param string $videoId
+	 * @param int $videoId
 	 * @return array|null
 	 */
-	public function getVideo(string $videoId): ?array {
+	public function getVideo(int $videoId): ?array {
 		// use field filtering, to save on quota, see: https://developer.vimeo.com/guidelines/rate-limiting
 		$fieldsToSelect = 'uri,name,description,link,embed,pictures,release_time,width,height';
 		try {
diff --git a/Resources/Private/Templates/Vimeo/Index.html b/Resources/Private/Templates/Vimeo/Index.html
index 78ccb9b..753258a 100644
--- a/Resources/Private/Templates/Vimeo/Index.html
+++ b/Resources/Private/Templates/Vimeo/Index.html
@@ -9,7 +9,6 @@
 
 	<f:variable name="feedCount" value="{response.items -> f:count()}"/>
 
-
 	<f:comment><!--Handle the container classes--></f:comment>
 	<f:variable name="classes">
 		<f:if condition="{feedCount} > 4">
@@ -116,7 +115,8 @@
 					<f:render section="vimeoItem" arguments="{
 						feedItem: feedItem,
 						titleChars: 100,
-						descChars: \"{f:if(condition: '{feedCount} < 3', then: '300', else: '90')}\"}" />
+						descChars: '{f:if(condition: \'{feedCount} < 3\', then: \'300\', else: \'90\')}'
+					}" />
 				</li>
 			</f:if>
 		</f:for>
@@ -125,7 +125,7 @@
 
 <f:section name="vimeoItem">
 	<div class="sg-video__item">
-		<a class="sg-video__image-container sg-vimeo-item" href="{feedItem.link}" target="_blank"
+		<a class="sg-video__image-container sg-vimeo-item" href="{f:if(condition: '{feedItem.embedLink}', then: '{feedItem.embedLink}', else: '{feedItem.link}')}" target="_blank"
 		   data-disable-lightbox="{settings.disableLightbox}"
 		   data-disable-lightbox-mobile="{settings.disableLightboxMobile}">
 			<f:if condition="{feedItem.thumbnail}">
@@ -136,7 +136,7 @@
 					<f:if condition="{feedItem.pictures.base_link}">
 						<img class="sg-video__image" src="{feedItem.pictures.base_link}_{feedItem.width}x{feedItem.height}?r=pad" alt="{item.name}" width="{feedItem.width}" height="{feedItem.height}" loading="lazy"/>
 					</f:if>
-					<f:comment>
+					<f:comment><!--
 						<f:if condition="{feedItem.pictures.sizes}">
 							<f:for each="{feedItem.pictures.sizes}" as="picture" iteration="iterator">
 								<f:if condition="{iterator.isLast}">
@@ -144,7 +144,7 @@
 								</f:if>
 							</f:for>
 						</f:if>
-					</f:comment>
+					--></f:comment>
 				</f:else>
 			</f:if>
 		</a>
diff --git a/Resources/Public/JavaScript/sgVimeoLightbox.js b/Resources/Public/JavaScript/sgVimeoLightbox.js
index c911de3..b0beae5 100644
--- a/Resources/Public/JavaScript/sgVimeoLightbox.js
+++ b/Resources/Public/JavaScript/sgVimeoLightbox.js
@@ -39,23 +39,22 @@ export default class SgVimeoLightbox {
 		const item = event.currentTarget;
 		item.classList.add('no-lightbox');
 
-		const videoId = this.getVideoIdFromUrl(item.href);
 		const videoImage = item.querySelector('.sg-video__image');
 		const height = videoImage.offsetHeight;
 		const width = videoImage.offsetWidth;
 
 		const iframe = document.createElement('iframe');
+		if (item.href.indexOf('?') > 0) {
+			iframe.src = item.href + '&dnt=1&autoplay=1';
+		} else {
+			iframe.src = item.href + '?dnt=1&autoplay=1';
+		}
 		iframe.width = width;
 		iframe.height = height;
 		iframe.style.border = 'none';
-		iframe.src = `https://player.vimeo.com/video/${videoId}?dnt=1&autoplay=1`;
 		iframe.allowFullscreen = true;
+		iframe.allow = 'autoplay; fullscreen; picture-in-picture';
 
 		item.replaceChild(iframe, videoImage);
 	}
-
-	getVideoIdFromUrl(url) {
-		const splitUrl = url.split('/');
-		return splitUrl[splitUrl.length - 1];
-	}
 }
-- 
GitLab