Initial code from customer project
This commit is contained in:
parent
835980d99c
commit
d61cdfe12f
18 changed files with 1341 additions and 0 deletions
34
Classes/AbstractOnlineMediaHelper.php
Normal file
34
Classes/AbstractOnlineMediaHelper.php
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2022 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Http\RequestFactory;
|
||||||
|
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\AbstractOnlineMediaHelper as Typo3AbstractOnlineMediaHelper;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
abstract class AbstractOnlineMediaHelper extends Typo3AbstractOnlineMediaHelper
|
||||||
|
{
|
||||||
|
protected function getRequestFactory(): RequestFactory
|
||||||
|
{
|
||||||
|
return GeneralUtility::makeInstance(RequestFactory::class);
|
||||||
|
}
|
||||||
|
}
|
137
Classes/Anchor/OnlineMediaHelper.php
Normal file
137
Classes/Anchor/OnlineMediaHelper.php
Normal file
|
@ -0,0 +1,137 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Anchor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Codappix\ExternalTypo3Multimedia\AbstractOnlineMediaHelper;
|
||||||
|
use Symfony\Component\DomCrawler\Crawler;
|
||||||
|
use TYPO3\CMS\Core\Http\Uri;
|
||||||
|
use TYPO3\CMS\Core\Resource\File;
|
||||||
|
use TYPO3\CMS\Core\Resource\Folder;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class OnlineMediaHelper extends AbstractOnlineMediaHelper
|
||||||
|
{
|
||||||
|
public function transformUrlToFile($url, Folder $targetFolder)
|
||||||
|
{
|
||||||
|
$mediaId = null;
|
||||||
|
$uri = new Uri($url);
|
||||||
|
if ($uri->getHost() === Registration::DOMAIN) {
|
||||||
|
$mediaId = trim($uri->getPath(), '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mediaId === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->findExistingFileByOnlineMediaId($mediaId, $targetFolder, $this->extension);
|
||||||
|
if ($file !== null) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileName = $mediaId . '.' . $this->extension;
|
||||||
|
$remoteData = $this->getRemoteData($mediaId);
|
||||||
|
if (!empty($remoteData['title'])) {
|
||||||
|
$fileName = $remoteData['title'] . '.' . $this->extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->createNewFile($targetFolder, $fileName, $mediaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPublicUrl(File $file, $relativeToCurrentScript = false)
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'https://' . Registration::DOMAIN . '/%s',
|
||||||
|
$this->getOnlineMediaId($file)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreviewImage(File $file)
|
||||||
|
{
|
||||||
|
$data = $this->getRemoteData($this->getOnlineMediaId($file));
|
||||||
|
if (isset($data['thumbnail_url']) === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageContent = GeneralUtility::getUrl($data['thumbnail_url']);
|
||||||
|
if ($imageContent === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tempName = GeneralUtility::tempnam($file->getNameWithoutExtension(), $file->getExtension());
|
||||||
|
GeneralUtility::writeFile($tempName, $imageContent);
|
||||||
|
|
||||||
|
return $tempName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMetaData(File $file)
|
||||||
|
{
|
||||||
|
$remoteData = $this->getRemoteData($this->getOnlineMediaId($file));
|
||||||
|
if ($remoteData === []) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$metadata = [
|
||||||
|
'width' => (int)$remoteData['width'],
|
||||||
|
'height' => (int)$remoteData['height'],
|
||||||
|
];
|
||||||
|
|
||||||
|
if (empty($file->getProperty('title'))) {
|
||||||
|
$metadata['title'] = strip_tags($remoteData['title']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($file->getProperty('description'))) {
|
||||||
|
$metadata['description'] = strip_tags($remoteData['description']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRemoteData(string $mediaId): array
|
||||||
|
{
|
||||||
|
static $data = [];
|
||||||
|
|
||||||
|
if (isset($data[$mediaId]) !== false) {
|
||||||
|
return $data[$mediaId];
|
||||||
|
}
|
||||||
|
|
||||||
|
$videoWebsite = $this->getRequestFactory()->request(
|
||||||
|
'https://' . Registration::DOMAIN . '/' . $mediaId
|
||||||
|
)->getBody()->getContents();
|
||||||
|
if ($videoWebsite === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$domCrawler = new Crawler($videoWebsite);
|
||||||
|
$remoteData = [
|
||||||
|
'title' => $domCrawler->filter('meta[property="og:title"]')->first()->attr('content'),
|
||||||
|
'description' => $domCrawler->filter('meta[name="description"]')->first()->attr('content'),
|
||||||
|
'width' => (int) $domCrawler->filter('meta[property="og:image:width"]')->first()->attr('content'),
|
||||||
|
'height' => (int) $domCrawler->filter('meta[property="og:image:height"]')->first()->attr('content'),
|
||||||
|
'thumbnail_url' => $domCrawler->filter('meta[property="og:image"]')->first()->attr('content'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$remoteData['title'] = str_replace(' • A podcast on Anchor', '', $remoteData['title']);
|
||||||
|
|
||||||
|
$data[$mediaId] = $remoteData;
|
||||||
|
return $remoteData;
|
||||||
|
}
|
||||||
|
}
|
55
Classes/Anchor/Registration.php
Normal file
55
Classes/Anchor/Registration.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Anchor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Resource\Rendering\RendererRegistry;
|
||||||
|
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||||
|
|
||||||
|
class Registration
|
||||||
|
{
|
||||||
|
public const FILE_EXTENSION = 'anchor';
|
||||||
|
|
||||||
|
public const FILE_MIME_TYPE = 'audio/anchor';
|
||||||
|
|
||||||
|
public const DOMAIN = 'anchor.fm';
|
||||||
|
|
||||||
|
public static function everything()
|
||||||
|
{
|
||||||
|
RendererRegistry::getInstance()->registerRendererClass(Renderer::class);
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext'] .= ',' . self::FILE_EXTENSION;
|
||||||
|
ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TYPO3_CONF_VARS'], [
|
||||||
|
'SYS' => [
|
||||||
|
'fal' => [
|
||||||
|
'onlineMediaHelpers' => [
|
||||||
|
self::FILE_EXTENSION => OnlineMediaHelper::class,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'FileInfo' => [
|
||||||
|
'fileExtensionToMimeType' => [
|
||||||
|
self::FILE_EXTENSION => self::FILE_MIME_TYPE,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
102
Classes/Anchor/Renderer.php
Normal file
102
Classes/Anchor/Renderer.php
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Anchor;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Codappix\ExternalTypo3Multimedia\IFrameRenderer;
|
||||||
|
use TYPO3\CMS\Core\Http\Uri;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileInterface;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileReference;
|
||||||
|
use TYPO3\CMS\Core\Resource\Rendering\FileRendererInterface;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class Renderer implements FileRendererInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var IFrameRenderer
|
||||||
|
*/
|
||||||
|
private $iframeRenderer;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
IFrameRenderer $iframeRenderer
|
||||||
|
) {
|
||||||
|
$this->iframeRenderer = $iframeRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriority()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canRender(FileInterface $file)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
$file->getMimeType() === Registration::FILE_MIME_TYPE
|
||||||
|
|| $file->getExtension() === Registration::FILE_EXTENSION
|
||||||
|
)
|
||||||
|
&& $this->iframeRenderer->getOnlineMediaHelper($file) !== false
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(
|
||||||
|
FileInterface $file,
|
||||||
|
$width,
|
||||||
|
$height,
|
||||||
|
array $options = [],
|
||||||
|
$usedPathsRelativeToCurrentScript = false
|
||||||
|
) {
|
||||||
|
$options = $this->iframeRenderer->collectOptions($options, $file);
|
||||||
|
$attributes = $this->iframeRenderer->collectAttributes('400px', '102px', $options);
|
||||||
|
$attributes['frameborder'] = 0;
|
||||||
|
$attributes['scrolling'] = 'no';
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<iframe src="%s"%s></iframe>',
|
||||||
|
htmlspecialchars($this->createUrl($options, $file), ENT_QUOTES | ENT_HTML5),
|
||||||
|
empty($attributes) ? '' : ' ' . GeneralUtility::implodeAttributes($attributes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createUrl(array $options, FileInterface $file)
|
||||||
|
{
|
||||||
|
if ($file instanceof FileReference) {
|
||||||
|
$file = $file->getOriginalFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = $this->iframeRenderer->getOnlineMediaHelper($file)->getPublicUrl($file);
|
||||||
|
$url = $this->addEmbedPathSegment($url);
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addEmbedPathSegment(string $url): string
|
||||||
|
{
|
||||||
|
$url = new Uri($url);
|
||||||
|
|
||||||
|
$pathSegments = GeneralUtility::trimExplode('/', $url->getPath(), true);
|
||||||
|
$url = $url->withPath(implode('/', array_merge([
|
||||||
|
$pathSegments[0],
|
||||||
|
'embed',
|
||||||
|
], array_slice($pathSegments, 1))));
|
||||||
|
|
||||||
|
return (string) $url;
|
||||||
|
}
|
||||||
|
}
|
139
Classes/Facebook/Video/OnlineMediaHelper.php
Normal file
139
Classes/Facebook/Video/OnlineMediaHelper.php
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Facebook\Video;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Codappix\ExternalTypo3Multimedia\AbstractOnlineMediaHelper;
|
||||||
|
use Symfony\Component\DomCrawler\Crawler;
|
||||||
|
use TYPO3\CMS\Core\Http\RequestFactory;
|
||||||
|
use TYPO3\CMS\Core\Http\Uri;
|
||||||
|
use TYPO3\CMS\Core\Resource\File;
|
||||||
|
use TYPO3\CMS\Core\Resource\Folder;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class OnlineMediaHelper extends AbstractOnlineMediaHelper
|
||||||
|
{
|
||||||
|
public function transformUrlToFile($url, Folder $targetFolder)
|
||||||
|
{
|
||||||
|
$mediaId = null;
|
||||||
|
$uri = new Uri($url);
|
||||||
|
if (
|
||||||
|
$uri->getHost() === Registration::DOMAIN
|
||||||
|
|| $uri->getHost() === 'www.facebook.com'
|
||||||
|
) {
|
||||||
|
$mediaId = trim($uri->getPath(), '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mediaId === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->findExistingFileByOnlineMediaId($mediaId, $targetFolder, $this->extension);
|
||||||
|
if ($file !== null) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileName = $mediaId . '.' . $this->extension;
|
||||||
|
$remoteData = $this->getRemoteData($mediaId);
|
||||||
|
if (!empty($remoteData['title'])) {
|
||||||
|
$fileName = $remoteData['title'] . '.' . $this->extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->createNewFile($targetFolder, $fileName, $mediaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPublicUrl(File $file, $relativeToCurrentScript = false)
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'https://' . Registration::DOMAIN . '/%s',
|
||||||
|
$this->getOnlineMediaId($file)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreviewImage(File $file)
|
||||||
|
{
|
||||||
|
$data = $this->getRemoteData($this->getOnlineMediaId($file));
|
||||||
|
if (isset($data['thumbnail_url']) === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageContent = GeneralUtility::getUrl($data['thumbnail_url']);
|
||||||
|
if ($imageContent === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tempName = GeneralUtility::tempnam($file->getNameWithoutExtension(), $file->getExtension());
|
||||||
|
GeneralUtility::writeFile($tempName, $imageContent);
|
||||||
|
|
||||||
|
return $tempName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMetaData(File $file)
|
||||||
|
{
|
||||||
|
$remoteData = $this->getRemoteData($this->getOnlineMediaId($file));
|
||||||
|
if ($remoteData === []) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$metadata = [
|
||||||
|
'width' => (int)$remoteData['width'],
|
||||||
|
'height' => (int)$remoteData['height'],
|
||||||
|
];
|
||||||
|
|
||||||
|
if (empty($file->getProperty('title'))) {
|
||||||
|
$metadata['title'] = strip_tags($remoteData['title']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($file->getProperty('description'))) {
|
||||||
|
$metadata['description'] = strip_tags($remoteData['description']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRemoteData(string $mediaId): array
|
||||||
|
{
|
||||||
|
static $data = [];
|
||||||
|
|
||||||
|
if (isset($data[$mediaId]) !== false) {
|
||||||
|
return $data[$mediaId];
|
||||||
|
}
|
||||||
|
|
||||||
|
$videoWebsite = $this->getRequestFactory()->request(
|
||||||
|
'https://www.facebook.com/' . $mediaId
|
||||||
|
)->getBody()->getContents();
|
||||||
|
if ($videoWebsite === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$domCrawler = new Crawler($videoWebsite);
|
||||||
|
$remoteData = [
|
||||||
|
'title' => $domCrawler->filter('meta[property="og:title"]')->first()->attr('content'),
|
||||||
|
'description' => $domCrawler->filter('meta[name="description"]')->first()->attr('content'),
|
||||||
|
'width' => (int) $domCrawler->filter('meta[property="og:video:width"]')->first()->attr('content'),
|
||||||
|
'height' => (int) $domCrawler->filter('meta[property="og:video:height"]')->first()->attr('content'),
|
||||||
|
'thumbnail_url' => $domCrawler->filter('meta[property="og:image"]')->first()->attr('content'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$data[$mediaId] = $remoteData;
|
||||||
|
return $remoteData;
|
||||||
|
}
|
||||||
|
}
|
55
Classes/Facebook/Video/Registration.php
Normal file
55
Classes/Facebook/Video/Registration.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Facebook\Video;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Resource\Rendering\RendererRegistry;
|
||||||
|
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||||
|
|
||||||
|
class Registration
|
||||||
|
{
|
||||||
|
public const FILE_EXTENSION = 'facebookvideo';
|
||||||
|
|
||||||
|
public const FILE_MIME_TYPE = 'video/facebook';
|
||||||
|
|
||||||
|
public const DOMAIN = 'facebook.com';
|
||||||
|
|
||||||
|
public static function everything()
|
||||||
|
{
|
||||||
|
RendererRegistry::getInstance()->registerRendererClass(Renderer::class);
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext'] .= ',' . self::FILE_EXTENSION;
|
||||||
|
ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TYPO3_CONF_VARS'], [
|
||||||
|
'SYS' => [
|
||||||
|
'fal' => [
|
||||||
|
'onlineMediaHelpers' => [
|
||||||
|
self::FILE_EXTENSION => OnlineMediaHelper::class,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'FileInfo' => [
|
||||||
|
'fileExtensionToMimeType' => [
|
||||||
|
self::FILE_EXTENSION => self::FILE_MIME_TYPE,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
83
Classes/Facebook/Video/Renderer.php
Normal file
83
Classes/Facebook/Video/Renderer.php
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Facebook\Video;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Codappix\ExternalTypo3Multimedia\IFrameRenderer;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileInterface;
|
||||||
|
use TYPO3\CMS\Core\Resource\Rendering\FileRendererInterface;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class Renderer implements FileRendererInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var IFrameRenderer
|
||||||
|
*/
|
||||||
|
private $iframeRenderer;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
IFrameRenderer $iframeRenderer
|
||||||
|
) {
|
||||||
|
$this->iframeRenderer = $iframeRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriority()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canRender(FileInterface $file)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
$file->getMimeType() === Registration::FILE_MIME_TYPE
|
||||||
|
|| $file->getExtension() === Registration::FILE_EXTENSION
|
||||||
|
)
|
||||||
|
&& $this->iframeRenderer->getOnlineMediaHelper($file) !== false
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(
|
||||||
|
FileInterface $file,
|
||||||
|
$width,
|
||||||
|
$height,
|
||||||
|
array $options = [],
|
||||||
|
$usedPathsRelativeToCurrentScript = false
|
||||||
|
) {
|
||||||
|
$options = $this->iframeRenderer->collectOptions($options, $file);
|
||||||
|
$attributes = $this->iframeRenderer->collectAttributes((int) $width, (int) $height, $options);
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<iframe src="%s"%s></iframe>',
|
||||||
|
htmlspecialchars($this->createUrl($options, $file), ENT_QUOTES | ENT_HTML5),
|
||||||
|
empty($attributes) ? '' : ' ' . GeneralUtility::implodeAttributes($attributes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createUrl(array $options, FileInterface $file)
|
||||||
|
{
|
||||||
|
$file = $this->iframeRenderer->getOriginalFile($file);
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'https://' . Registration::DOMAIN . '/plugins/video.php?href=%s',
|
||||||
|
rawurlencode($this->iframeRenderer->getOnlineMediaHelper($file)->getPublicUrl($file))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
134
Classes/IFrameRenderer.php
Normal file
134
Classes/IFrameRenderer.php
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Resource\File;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileInterface;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileReference;
|
||||||
|
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperInterface;
|
||||||
|
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides common API to generate iFrames for external multimedia.
|
||||||
|
*/
|
||||||
|
class IFrameRenderer
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Generates pairs of key/value; not yet html-escaped
|
||||||
|
*/
|
||||||
|
public function collectAttributes(
|
||||||
|
string $width,
|
||||||
|
string $height,
|
||||||
|
array $options
|
||||||
|
): array {
|
||||||
|
$attributes = [];
|
||||||
|
$attributes['allowfullscreen'] = true;
|
||||||
|
|
||||||
|
if (isset($options['additionalAttributes']) && is_array($options['additionalAttributes'])) {
|
||||||
|
$attributes = array_merge($attributes, $options['additionalAttributes']);
|
||||||
|
}
|
||||||
|
if (isset($options['data']) && is_array($options['data'])) {
|
||||||
|
array_walk(
|
||||||
|
$options['data'],
|
||||||
|
function (&$value, $key) use (&$attributes) {
|
||||||
|
$attributes['data-' . $key] = $value;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if ($width !== '' && $width !== 0) {
|
||||||
|
$attributes['width'] = htmlspecialchars($width);
|
||||||
|
}
|
||||||
|
if ($height !== '' && $height !== 0) {
|
||||||
|
$attributes['height'] = htmlspecialchars($height);
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
isset($GLOBALS['TSFE'])
|
||||||
|
&& is_object($GLOBALS['TSFE'])
|
||||||
|
&& (
|
||||||
|
isset($GLOBALS['TSFE']->config['config']['doctype'])
|
||||||
|
&& $GLOBALS['TSFE']->config['config']['doctype'] !== 'html5'
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
$attributes['frameborder'] = 0;
|
||||||
|
}
|
||||||
|
$allowedAttributes = [
|
||||||
|
'class',
|
||||||
|
'dir',
|
||||||
|
'id',
|
||||||
|
'lang',
|
||||||
|
'style',
|
||||||
|
'title',
|
||||||
|
'accesskey',
|
||||||
|
'tabindex',
|
||||||
|
'onclick',
|
||||||
|
'allow',
|
||||||
|
];
|
||||||
|
foreach ($allowedAttributes as $key) {
|
||||||
|
if (!empty($options[$key])) {
|
||||||
|
$attributes[$key] = $options[$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$attributes = array_map('htmlspecialchars', $attributes);
|
||||||
|
|
||||||
|
return $attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function collectOptions(
|
||||||
|
array $options,
|
||||||
|
FileInterface $file
|
||||||
|
): array {
|
||||||
|
// Check for an autoplay option at the file reference itself, if not overridden yet.
|
||||||
|
if (!isset($options['autoplay']) && $file instanceof FileReference) {
|
||||||
|
$autoplay = $file->getProperty('autoplay');
|
||||||
|
if ($autoplay !== null) {
|
||||||
|
$options['autoplay'] = $autoplay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($options['allow'])) {
|
||||||
|
$options['allow'] = 'fullscreen';
|
||||||
|
if (!empty($options['autoplay'])) {
|
||||||
|
$options['allow'] = 'autoplay; fullscreen';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOriginalFile(FileInterface $file): File
|
||||||
|
{
|
||||||
|
$orgFile = $file;
|
||||||
|
|
||||||
|
if ($orgFile instanceof FileReference) {
|
||||||
|
$orgFile = $orgFile->getOriginalFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $orgFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOnlineMediaHelper(FileInterface $file): OnlineMediaHelperInterface
|
||||||
|
{
|
||||||
|
return OnlineMediaHelperRegistry::getInstance()
|
||||||
|
->getOnlineMediaHelper($this->getOriginalFile($file));
|
||||||
|
}
|
||||||
|
}
|
107
Classes/Soundcloud/OnlineMediaHelper.php
Normal file
107
Classes/Soundcloud/OnlineMediaHelper.php
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Soundcloud;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Http\Uri;
|
||||||
|
use TYPO3\CMS\Core\Resource\File;
|
||||||
|
use TYPO3\CMS\Core\Resource\Folder;
|
||||||
|
use TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\AbstractOEmbedHelper;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class OnlineMediaHelper extends AbstractOEmbedHelper
|
||||||
|
{
|
||||||
|
public function transformUrlToFile($url, Folder $targetFolder)
|
||||||
|
{
|
||||||
|
$id = null;
|
||||||
|
$uri = new Uri($url);
|
||||||
|
if ($uri->getHost() === Registration::DOMAIN) {
|
||||||
|
$id = trim($uri->getPath(), '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($id === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->transformMediaIdToFile($id, $targetFolder, $this->extension);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPublicUrl(File $file, $relativeToCurrentScript = false)
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'https://' . Registration::DOMAIN . '/%s',
|
||||||
|
$this->getOnlineMediaId($file)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreviewImage(File $file)
|
||||||
|
{
|
||||||
|
$data = $this->getOEmbedData($this->getOnlineMediaId($file));
|
||||||
|
|
||||||
|
if ($data === false || isset($data['thumbnail_url']) === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageContent = GeneralUtility::getUrl($data['thumbnail_url']);
|
||||||
|
if ($imageContent === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tempName = GeneralUtility::tempnam($file->getNameWithoutExtension(), $file->getExtension());
|
||||||
|
GeneralUtility::writeFile($tempName, $imageContent);
|
||||||
|
|
||||||
|
return $tempName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap original to add caching.
|
||||||
|
// Otherwise foreign API might be called multiple times.
|
||||||
|
protected function getOEmbedData($mediaId)
|
||||||
|
{
|
||||||
|
static $data = [];
|
||||||
|
|
||||||
|
if (isset($data[$mediaId]) === false) {
|
||||||
|
$data[$mediaId] = parent::getOEmbedData($mediaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $data[$mediaId];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMetaData(File $file)
|
||||||
|
{
|
||||||
|
$oEmbed = $this->getOEmbedData($this->getOnlineMediaId($file));
|
||||||
|
$metadata = parent::getMetaData($file);
|
||||||
|
|
||||||
|
if (empty($file->getProperty('description'))) {
|
||||||
|
$metadata['description'] = strip_tags($oEmbed['description']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function getOEmbedUrl($mediaId, $format = 'json')
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'https://' . Registration::DOMAIN . '/oembed?format=%s&url=%s',
|
||||||
|
rawurlencode($format),
|
||||||
|
sprintf('https://' . Registration::DOMAIN . '/%s', $mediaId)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
57
Classes/Soundcloud/Registration.php
Normal file
57
Classes/Soundcloud/Registration.php
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Soundcloud;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Resource\Rendering\RendererRegistry;
|
||||||
|
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||||
|
|
||||||
|
class Registration
|
||||||
|
{
|
||||||
|
public const FILE_EXTENSION = 'soundcloud';
|
||||||
|
|
||||||
|
public const FILE_MIME_TYPE = 'audio/soundcloud';
|
||||||
|
|
||||||
|
public const DOMAIN = 'soundcloud.com';
|
||||||
|
|
||||||
|
public const EMBED_DOMAIN = 'w.soundcloud.com';
|
||||||
|
|
||||||
|
public static function everything()
|
||||||
|
{
|
||||||
|
RendererRegistry::getInstance()->registerRendererClass(Renderer::class);
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext'] .= ',' . self::FILE_EXTENSION;
|
||||||
|
ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TYPO3_CONF_VARS'], [
|
||||||
|
'SYS' => [
|
||||||
|
'fal' => [
|
||||||
|
'onlineMediaHelpers' => [
|
||||||
|
self::FILE_EXTENSION => OnlineMediaHelper::class,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'FileInfo' => [
|
||||||
|
'fileExtensionToMimeType' => [
|
||||||
|
self::FILE_EXTENSION => self::FILE_MIME_TYPE,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
89
Classes/Soundcloud/Renderer.php
Normal file
89
Classes/Soundcloud/Renderer.php
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Soundcloud;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Codappix\ExternalTypo3Multimedia\IFrameRenderer;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileInterface;
|
||||||
|
use TYPO3\CMS\Core\Resource\Rendering\FileRendererInterface;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class Renderer implements FileRendererInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var IFrameRenderer
|
||||||
|
*/
|
||||||
|
private $iframeRenderer;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
IFrameRenderer $iframeRenderer
|
||||||
|
) {
|
||||||
|
$this->iframeRenderer = $iframeRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriority()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canRender(FileInterface $file)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
$file->getMimeType() === Registration::FILE_MIME_TYPE
|
||||||
|
|| $file->getExtension() === Registration::FILE_EXTENSION
|
||||||
|
)
|
||||||
|
&& $this->iframeRenderer->getOnlineMediaHelper($file) !== false
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(
|
||||||
|
FileInterface $file,
|
||||||
|
$width,
|
||||||
|
$height,
|
||||||
|
array $options = [],
|
||||||
|
$usedPathsRelativeToCurrentScript = false
|
||||||
|
) {
|
||||||
|
$options = $this->iframeRenderer->collectOptions($options, $file);
|
||||||
|
$attributes = $this->iframeRenderer->collectAttributes($width . '%', $height, $options);
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<iframe src="%s"%s></iframe>',
|
||||||
|
htmlspecialchars($this->createUrl($options, $file), ENT_QUOTES | ENT_HTML5),
|
||||||
|
empty($attributes) ? '' : ' ' . GeneralUtility::implodeAttributes($attributes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createUrl(array $options, FileInterface $file)
|
||||||
|
{
|
||||||
|
$urlParams = [];
|
||||||
|
if (!empty($options['autoplay'])) {
|
||||||
|
$urlParams[] = 'auto_play=1';
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->iframeRenderer->getOriginalFile($file);
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'https://' . Registration::EMBED_DOMAIN . '/player/?url=%s?%s',
|
||||||
|
rawurlencode($this->iframeRenderer->getOnlineMediaHelper($file)->getPublicUrl($file)),
|
||||||
|
implode('&', $urlParams)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
133
Classes/Spotify/OnlineMediaHelper.php
Normal file
133
Classes/Spotify/OnlineMediaHelper.php
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Spotify;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Codappix\ExternalTypo3Multimedia\AbstractOnlineMediaHelper;
|
||||||
|
use Symfony\Component\DomCrawler\Crawler;
|
||||||
|
use TYPO3\CMS\Core\Http\Uri;
|
||||||
|
use TYPO3\CMS\Core\Resource\File;
|
||||||
|
use TYPO3\CMS\Core\Resource\Folder;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class OnlineMediaHelper extends AbstractOnlineMediaHelper
|
||||||
|
{
|
||||||
|
public function transformUrlToFile($url, Folder $targetFolder)
|
||||||
|
{
|
||||||
|
$mediaId = null;
|
||||||
|
$uri = new Uri($url);
|
||||||
|
if ($uri->getHost() === Registration::DOMAIN) {
|
||||||
|
$mediaId = trim($uri->getPath(), '/');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mediaId === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$file = $this->findExistingFileByOnlineMediaId($mediaId, $targetFolder, $this->extension);
|
||||||
|
if ($file !== null) {
|
||||||
|
return $file;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileName = $mediaId . '.' . $this->extension;
|
||||||
|
$remoteData = $this->getRemoteData($mediaId);
|
||||||
|
if (!empty($remoteData['title'])) {
|
||||||
|
$fileName = $remoteData['title'] . '.' . $this->extension;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->createNewFile($targetFolder, $fileName, $mediaId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPublicUrl(File $file, $relativeToCurrentScript = false)
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'https://' . Registration::DOMAIN . '/%s',
|
||||||
|
$this->getOnlineMediaId($file)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPreviewImage(File $file)
|
||||||
|
{
|
||||||
|
$data = $this->getRemoteData($this->getOnlineMediaId($file));
|
||||||
|
if (isset($data['thumbnail_url']) === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$imageContent = GeneralUtility::getUrl($data['thumbnail_url']);
|
||||||
|
if ($imageContent === false) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tempName = GeneralUtility::tempnam($file->getNameWithoutExtension(), $file->getExtension());
|
||||||
|
GeneralUtility::writeFile($tempName, $imageContent);
|
||||||
|
|
||||||
|
return $tempName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMetaData(File $file)
|
||||||
|
{
|
||||||
|
$remoteData = $this->getRemoteData($this->getOnlineMediaId($file));
|
||||||
|
if ($remoteData === []) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$metadata = [
|
||||||
|
'width' => (int)$remoteData['width'],
|
||||||
|
'height' => (int)$remoteData['height'],
|
||||||
|
];
|
||||||
|
|
||||||
|
if (empty($file->getProperty('title'))) {
|
||||||
|
$metadata['title'] = strip_tags($remoteData['title']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($file->getProperty('description'))) {
|
||||||
|
$metadata['description'] = strip_tags($remoteData['description']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $metadata;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRemoteData(string $mediaId): array
|
||||||
|
{
|
||||||
|
static $data = [];
|
||||||
|
|
||||||
|
if (isset($data[$mediaId]) !== false) {
|
||||||
|
return $data[$mediaId];
|
||||||
|
}
|
||||||
|
|
||||||
|
$videoWebsite = $this->getRequestFactory()->request(
|
||||||
|
'https://' . Registration::DOMAIN . '/' . $mediaId
|
||||||
|
)->getBody()->getContents();
|
||||||
|
if ($videoWebsite === '') {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$domCrawler = new Crawler($videoWebsite);
|
||||||
|
$remoteData = [
|
||||||
|
'title' => $domCrawler->filter('meta[property="og:title"]')->first()->attr('content'),
|
||||||
|
'description' => $domCrawler->filter('meta[name="description"]')->first()->attr('content'),
|
||||||
|
'thumbnail_url' => $domCrawler->filter('meta[property="og:image"]')->first()->attr('content'),
|
||||||
|
];
|
||||||
|
|
||||||
|
$data[$mediaId] = $remoteData;
|
||||||
|
return $remoteData;
|
||||||
|
}
|
||||||
|
}
|
55
Classes/Spotify/Registration.php
Normal file
55
Classes/Spotify/Registration.php
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Spotify;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use TYPO3\CMS\Core\Resource\Rendering\RendererRegistry;
|
||||||
|
use TYPO3\CMS\Core\Utility\ArrayUtility;
|
||||||
|
|
||||||
|
class Registration
|
||||||
|
{
|
||||||
|
public const FILE_EXTENSION = 'spotify';
|
||||||
|
|
||||||
|
public const FILE_MIME_TYPE = 'audio/spotify';
|
||||||
|
|
||||||
|
public const DOMAIN = 'open.spotify.com';
|
||||||
|
|
||||||
|
public static function everything()
|
||||||
|
{
|
||||||
|
RendererRegistry::getInstance()->registerRendererClass(Renderer::class);
|
||||||
|
|
||||||
|
$GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext'] .= ',' . self::FILE_EXTENSION;
|
||||||
|
ArrayUtility::mergeRecursiveWithOverrule($GLOBALS['TYPO3_CONF_VARS'], [
|
||||||
|
'SYS' => [
|
||||||
|
'fal' => [
|
||||||
|
'onlineMediaHelpers' => [
|
||||||
|
self::FILE_EXTENSION => OnlineMediaHelper::class,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
'FileInfo' => [
|
||||||
|
'fileExtensionToMimeType' => [
|
||||||
|
self::FILE_EXTENSION => self::FILE_MIME_TYPE,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
}
|
96
Classes/Spotify/Renderer.php
Normal file
96
Classes/Spotify/Renderer.php
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Codappix\ExternalTypo3Multimedia\Spotify;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Daniel Siepmann <coding@daniel-siepmann.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||||
|
* 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use Codappix\ExternalTypo3Multimedia\IFrameRenderer;
|
||||||
|
use TYPO3\CMS\Core\Http\Uri;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileInterface;
|
||||||
|
use TYPO3\CMS\Core\Resource\FileReference;
|
||||||
|
use TYPO3\CMS\Core\Resource\Rendering\FileRendererInterface;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
|
class Renderer implements FileRendererInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var IFrameRenderer
|
||||||
|
*/
|
||||||
|
private $iframeRenderer;
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
IFrameRenderer $iframeRenderer
|
||||||
|
) {
|
||||||
|
$this->iframeRenderer = $iframeRenderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPriority()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function canRender(FileInterface $file)
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
$file->getMimeType() === Registration::FILE_MIME_TYPE
|
||||||
|
|| $file->getExtension() === Registration::FILE_EXTENSION
|
||||||
|
)
|
||||||
|
&& $this->iframeRenderer->getOnlineMediaHelper($file) !== false
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function render(
|
||||||
|
FileInterface $file,
|
||||||
|
$width,
|
||||||
|
$height,
|
||||||
|
array $options = [],
|
||||||
|
$usedPathsRelativeToCurrentScript = false
|
||||||
|
) {
|
||||||
|
$options = $this->iframeRenderer->collectOptions($options, $file);
|
||||||
|
$attributes = $this->iframeRenderer->collectAttributes('100%', '235px', $options);
|
||||||
|
$attributes['allowtransparency'] = 'true';
|
||||||
|
$attributes['allow'] = 'encrypted-media';
|
||||||
|
|
||||||
|
return sprintf(
|
||||||
|
'<iframe src="%s"%s></iframe>',
|
||||||
|
htmlspecialchars($this->createUrl($options, $file), ENT_QUOTES | ENT_HTML5),
|
||||||
|
empty($attributes) ? '' : ' ' . GeneralUtility::implodeAttributes($attributes)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function createUrl(array $options, FileInterface $file)
|
||||||
|
{
|
||||||
|
if ($file instanceof FileReference) {
|
||||||
|
$file = $file->getOriginalFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
$url = $this->iframeRenderer->getOnlineMediaHelper($file)->getPublicUrl($file);
|
||||||
|
$url = $this->addEmbedPathSegment($url);
|
||||||
|
|
||||||
|
return $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function addEmbedPathSegment(string $url): string
|
||||||
|
{
|
||||||
|
$url = new Uri($url);
|
||||||
|
$url = $url->withPath('embed-podcast/' . ltrim($url->getPath(), '/'));
|
||||||
|
return (string) $url;
|
||||||
|
}
|
||||||
|
}
|
8
Configuration/Services.yaml
Normal file
8
Configuration/Services.yaml
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
services:
|
||||||
|
_defaults:
|
||||||
|
autowire: true
|
||||||
|
autoconfigure: true
|
||||||
|
public: false
|
||||||
|
|
||||||
|
Codappix\ExternalTypo3Multimedia\:
|
||||||
|
resource: '../Classes/*'
|
28
composer.json
Normal file
28
composer.json
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "codappix/external-typo3-multimedia",
|
||||||
|
"type": "typo3-cms-extension",
|
||||||
|
"description": "Provide integration of external multimedia like Soundcloud and Facebook videos",
|
||||||
|
"license": "GPL-2.0-or-later",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Daniel Siepmann",
|
||||||
|
"email": "coding@daniel-siepmann.de",
|
||||||
|
"role": "Developer"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"require": {
|
||||||
|
"typo3/cms-core": "^10.4",
|
||||||
|
"symfony/dom-crawler": "^5.0"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Codappix\\ExternalTypo3Multimedia\\": "Classes/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extra": {
|
||||||
|
"typo3/cms": {
|
||||||
|
"extension-key": "external_multimedia"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
ext_emconf.php
Normal file
21
ext_emconf.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$EM_CONF['external_multimedia'] = [
|
||||||
|
'title' => 'Support External Multimedia',
|
||||||
|
'description' => 'Add support for media like Soundcloud or Facebook videos.',
|
||||||
|
'category' => 'plugin',
|
||||||
|
'author' => 'Daniel Siepmann',
|
||||||
|
'author_email' => 'coding@daniel-siepmann.de',
|
||||||
|
'author_company' => 'Codappix GmbH',
|
||||||
|
'state' => 'beta',
|
||||||
|
'version' => '1.0.0',
|
||||||
|
'constraints' => [
|
||||||
|
'depends' => [
|
||||||
|
'typo3' => '*',
|
||||||
|
],
|
||||||
|
'conflicts' => [
|
||||||
|
],
|
||||||
|
'suggests' => [
|
||||||
|
],
|
||||||
|
],
|
||||||
|
];
|
8
ext_localconf.php
Normal file
8
ext_localconf.php
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
defined('TYPO3_MODE') or die();
|
||||||
|
|
||||||
|
\Codappix\ExternalTypo3Multimedia\Anchor\Registration::everything();
|
||||||
|
\Codappix\ExternalTypo3Multimedia\Soundcloud\Registration::everything();
|
||||||
|
\Codappix\ExternalTypo3Multimedia\Spotify\Registration::everything();
|
||||||
|
\Codappix\ExternalTypo3Multimedia\Facebook\Video\Registration::everything();
|
Loading…
Reference in a new issue