Project

General

Profile

Feature #90680 » FacebookHelper.php

Robert von Hackwitz, 2020-03-08 12:05

 
<?php
namespace TYPO3\CMS\Core\Resource\OnlineMedia\Helpers;

/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/

use TYPO3\CMS\Core\Resource\File;
use TYPO3\CMS\Core\Resource\Folder;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
* Facebook helper class
*
* @author Robert von Hackwitz <hostmaster@usb.it>
*/
class FacebookHelper extends AbstractOEmbedHelper
{
/**
* @param \TYPO3\CMS\Core\Resource\File $file
* @param bool $relativeToCurrentScript
* @return string
*/
public function getPublicUrl(\TYPO3\CMS\Core\Resource\File $file, $relativeToCurrentScript = false)
{
$videoIdFromFile = '';
$facebookUrl = '';
$videoIdParts = [];
$videoIdFromFile = $this->getOnlineMediaId($file);
$videoIdParts = $this->getOnlineMediaIdParts($videoIdFromFile);
if ($videoIdParts[0]!=='' && $videoIdParts[1]!=='') {
$facebookUrl = sprintf(
'https://www.facebook.com/plugins/video.php?href=https://www.facebook.com/%s/videos/%s',
$videoIdParts['channel'],
$videoIdParts['videoid']
);
}

return $facebookUrl;

}
/**
* Get local absolute file path to preview image
* Unlike Youtube videos on Facebook there aren't well defined thumbs locations like https://img.youtube ...
* so we use a little trick: We know that on the video page there is one image ONLY which is the preview and we
* get it using DOMDocument. No complications with api graph ...
*
* @param File $file
* @return string
*/
public function getPreviewImage(File $file)
{
$videoId = $this->getOnlineMediaId($file);
$temporaryFileName = $this->getTempFolderPath() . 'facebook_' . md5($videoId) . '.jpg';
if (!file_exists($temporaryFileName)) {
$fbPage = GeneralUtility::getUrl($this->getPublicUrl($file));
$dom = new \DOMDocument;
@$dom->loadHTML($fbPage);
$tags = $dom->getElementsByTagName('img');
$imgSrc = $tags[0]->getAttribute('src');
if($imgSrc!='') {
$previewImage = GeneralUtility::getUrl($imgSrc);
if ($previewImage !== false) {
file_put_contents($temporaryFileName, $previewImage);
GeneralUtility::fixPermissions($temporaryFileName);
}
}
}
return $temporaryFileName;
}
/**
* Try to transform given URL to a File
*
* @param string $url
* @param Folder $targetFolder
* @return File|null
*/
public function transformUrlToFile($url, Folder $targetFolder)
{

$videoId = null;
$matches = [];
/**
* First let's try the simpliest way.
* TODO: other url types
* Unlike Youtube and Vimeo we have to get both {user-id} or {page-id} and {video-id} and store them
*/
if (preg_match('/facebook\.com\/(.*)\/videos\/*([0-9]+)/i', $url, $matches)) {
// Video Id = Channel name + '_' + Video ID
$videoId = $matches[1] . '_' . $matches[2];
}
if (empty($videoId)) {
return null;
}

return $this->transformMediaIdToFile($videoId, $targetFolder, $this->extension);
}
/**
* Get oEmbed url to retrieve oEmbed data
*
* Method implemented but Facebook oEmbed doesn't return title ...
*
* @param string $mediaId
* @param string $format
* @return string
*/
protected function getOEmbedUrl($mediaId, $format = 'json')
{

$videoIdParts = $this->getOnlineMediaIdParts($mediaId);
$videoUrl = sprintf(
'https://www.facebook.com/%s/videos/%s/',
$videoIdParts['channel'],
$videoIdParts['videoid']
);
$oEmbedUrl = sprintf(
'https://www.facebook.com/plugins/video/oembed.%s/?url=%s',
rawurlencode($format),
rawurlencode($videoUrl)
);

return $oEmbedUrl;
}
/**
* Get Facebook video id parts
*
* We need this beecause video urls on Facebook are identified by {user-id} or {page-id} + {video-id}
*
* @param string $videoId
* @return array
*/
protected function getOnlineMediaIdParts(string $videoId) {
$videoIdArr = GeneralUtility::trimExplode('_', $videoId);
$ch = $videoIdArr[0];
$id = $videoIdArr[1];
return ['channel'=> $ch, 'videoid' => $id];
}
}
(1-1/2)