forked from leftypol/leftypol
EmbedService.php: move to right namespace
This commit is contained in:
parent
811698d9ef
commit
28a747b335
1 changed files with 2 additions and 2 deletions
141
inc/Service/Embed/EmbedService.php
Normal file
141
inc/Service/Embed/EmbedService.php
Normal file
|
@ -0,0 +1,141 @@
|
|||
<?php
|
||||
namespace Vichan\Service\Embed;
|
||||
|
||||
use Vichan\Service\Embed\OembedExtractor;
|
||||
use Vichan\Data\Driver\{HttpDriver, LogDriver};
|
||||
|
||||
|
||||
class EmbedService {
|
||||
private const TMP_FILE_PREFIX = 'oembed-thumb-';
|
||||
|
||||
private LogDriver $log;
|
||||
private OembedExtractor $oembed_extractor;
|
||||
private HttpDriver $http;
|
||||
private string $tmp_dir;
|
||||
private array $embed_entries;
|
||||
private int $thumb_download_timeout;
|
||||
|
||||
|
||||
public function __construct(LogDriver $log, OembedExtractor $oembed_extractor, array $embed_entries, int $thumb_download_timeout) {
|
||||
$this->log = $log;
|
||||
$this->oembed_extractor = $oembed_extractor;
|
||||
$this->embed_entries = $embed_entries;
|
||||
$this->thumb_download_timeout = $thumb_download_timeout;
|
||||
}
|
||||
|
||||
private function make_tmp_file(): string {
|
||||
$ret = \tempnam($this->tmp_dir, self::TMP_FILE_PREFIX);
|
||||
if ($ret === false) {
|
||||
throw new \RuntimeException("Could not create temporary file in {$this->tmp_dir}");
|
||||
}
|
||||
\register_shutdown_function(fn() => @unlink($ret));
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads the thumbnail into a temporary file.
|
||||
*
|
||||
* @return ?string The path to the temporary file, null if the file was too large.
|
||||
*/
|
||||
private function fetchThumbnail(string $thumbnail_url): ?string {
|
||||
$tmp_file = $this->make_tmp_file();
|
||||
$fd = \fopen($tmp_file, 'w+b');
|
||||
if ($fd === false) {
|
||||
throw new \RuntimeException("Could not open temporary file $tmp_file for read/write");
|
||||
}
|
||||
|
||||
$ret = $this->http->requestGetInto($thumbnail_url, null, $fd, $this->thumb_download_timeout);
|
||||
return $ret ? $tmp_file : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the path to the thumbnail from a matched url, if any.
|
||||
*
|
||||
* @param string $url The url to embed.
|
||||
* @param int $entry_index The index of the embedding entry.
|
||||
* @return ?array Returns the url to the thumbnail and the path to the fallback.
|
||||
*/
|
||||
private function extractThumb(string $url, int $entry_index) {
|
||||
$embed_entry = $this->embed_entries[$entry_index];
|
||||
$match_regex = $embed_entry['match_regex'];
|
||||
$type = $embed_entry['type'];
|
||||
|
||||
if ($type === 'oembed') {
|
||||
$thumbnail_url_fallback = $embed_entry['thumbnail_url_fallback'] ?? null;
|
||||
$provider = $embed_entry['provider_url'];
|
||||
$oembed_resp = $this->oembed_extractor->fetch($provider, $url);
|
||||
|
||||
return [ $oembed_resp->thumbnail_url, $thumbnail_url_fallback ];
|
||||
} elseif ($type === 'regex') {
|
||||
$thumbnail_url_regex = $embed_entry['thumbnail_url'];
|
||||
// Plz somebody review this.
|
||||
return [ \preg_replace($match_regex, $thumbnail_url_regex, $url), null ];
|
||||
} else {
|
||||
$this->log->log(LogDriver::ERROR, "Unknown embed type '$type' in embed entry $entry_index, ignoring the entry");
|
||||
return [ null, null ];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the embed entry matching with the url, if any.
|
||||
*
|
||||
* @param string $url Url to embed. MUST BE ALREADY VALIDATED.
|
||||
* @return int The index of the matched embed entry or null.
|
||||
*/
|
||||
public function matchEmbed(string $url): ?int {
|
||||
for ($i = 0; $i < \count($this->embed_entries); $i++) {
|
||||
$match_regex = $this->embed_entries[$i]['match_regex'];
|
||||
if (\preg_match($match_regex, $url, $matches)) {
|
||||
return $i;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the embed's thumbnail if possible. May download it from the network into a temporary file, or use a static file.
|
||||
*
|
||||
* @param string $url Url to embed. MUST BE ALREADY VALIDATED.
|
||||
* @param int The index of the matched embed entry.
|
||||
* @return ?array Null if no thumbnail can be selected, otherwise an array with the local file path to the thumbnail
|
||||
* and if the the file is a temporary or a static one.
|
||||
*/
|
||||
public function getEmbedThumb(string $url, int $entry_index): ?array {
|
||||
$ret = $this->extractThumb($url, $entry_index);
|
||||
list($thumbnail_url, $thumbnail_url_fallback) = $ret;
|
||||
if (!isset($thumbnail_url, $thumbnail_url_fallback)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (\filter_var($thumbnail_url, \FILTER_VALIDATE_URL) === false) {
|
||||
$this->log->log(LogDriver::ERROR, "Thumbnail URL '$thumbnail_url' from embed entry $entry_index is not a valid URL, trying fallback");
|
||||
} else {
|
||||
$tmp_file = $this->fetchThumbnail($thumbnail_url);
|
||||
if ($tmp_file !== null) {
|
||||
return [ $tmp_file, true ];
|
||||
}
|
||||
$this->log->log(LogDriver::NOTICE, "Thumbnail at '$thumbnail_url' was too large, trying fallback");
|
||||
}
|
||||
|
||||
if ($thumbnail_url_fallback === null) {
|
||||
return null;
|
||||
}
|
||||
return [ $thumbnail_url_fallback, false ];
|
||||
}
|
||||
|
||||
public function renderEmbed(string $url, int $entry_index, string $thumbnail_path): string {
|
||||
$embed_entry = $this->embed_entries[$entry_index];
|
||||
$match_regex = $embed_entry['match_regex'];
|
||||
$html = $embed_entry['html'];
|
||||
|
||||
$ret = \preg_replace($match_regex, $html, $url);
|
||||
if (!\is_string($ret)) {
|
||||
throw new \RuntimeException("Error while applying regex replacement for embed entry $entry_index");
|
||||
}
|
||||
|
||||
\str_replace('%%embed_url%%', $url, $ret);
|
||||
\str_replace('%%thumbnail_path%%', $thumbnail_path, $ret);
|
||||
return $ret;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue