2025-03-16 23:26:45 +01:00
|
|
|
<?php
|
2025-03-18 09:59:16 +01:00
|
|
|
namespace Vichan\Service\Embed;
|
2025-03-16 23:26:45 +01:00
|
|
|
|
|
|
|
use Vichan\Data\Driver\{CacheDriver, HttpDriver};
|
|
|
|
use Vichan\Data\OembedResponse;
|
|
|
|
|
|
|
|
|
|
|
|
class OembedExtractor {
|
|
|
|
private const DEFAULT_CACHE_TIMEOUT = 3600; // 1 hour.
|
2025-03-17 12:47:08 +01:00
|
|
|
private const MIN_CACHE_TIMEOUT = 900; // 15 minutes.
|
2025-03-16 23:26:45 +01:00
|
|
|
|
|
|
|
private CacheDriver $cache;
|
|
|
|
private HttpDriver $http;
|
|
|
|
private int $provider_timeout;
|
|
|
|
|
|
|
|
|
|
|
|
public function __construct(CacheDriver $cache, HttpDriver $http, int $provider_timeout) {
|
|
|
|
$this->cache = $cache;
|
|
|
|
$this->http = $http;
|
|
|
|
$this->provider_timeout = $provider_timeout;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fetch the oembed data from the given provider with the given url.
|
|
|
|
*
|
|
|
|
* @param string $identifier Opaque identifier for caching, must be unique for each $url-$provider combination.
|
|
|
|
* @return OembedResponse The serialized remove response. May be cached.
|
|
|
|
*/
|
|
|
|
public function fetch(string $provider_url, string $url): OembedResponse {
|
|
|
|
$ret = $this->cache->get("oembed_embedder_$provider_url$url");
|
|
|
|
if ($ret === null) {
|
|
|
|
$body = $this->http->requestGet(
|
|
|
|
$provider_url,
|
|
|
|
[
|
|
|
|
'url' => $url,
|
|
|
|
'format' => 'json'
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'Content-Type: application/json'
|
|
|
|
],
|
|
|
|
$this->provider_timeout
|
|
|
|
);
|
2025-03-28 11:06:24 +01:00
|
|
|
$json = \json_decode($body, true, 512, \JSON_THROW_ON_ERROR);
|
2025-03-16 23:26:45 +01:00
|
|
|
|
|
|
|
$ret = [
|
2025-03-17 12:47:08 +01:00
|
|
|
'title' => $json['title'] ?? null,
|
|
|
|
'thumbnail_url' => $json['thumbnail_url'] ?? null,
|
2025-03-16 23:26:45 +01:00
|
|
|
];
|
|
|
|
|
2025-03-17 12:47:08 +01:00
|
|
|
$cache_timeout = self::DEFAULT_CACHE_TIMEOUT;
|
|
|
|
if (isset($json['cache_age'])) {
|
|
|
|
$cache_age = \intval($json['cache_age']);
|
|
|
|
if ($cache_age > 0) {
|
|
|
|
$cache_age = \max($cache_age, self::MIN_CACHE_TIMEOUT);
|
|
|
|
}
|
|
|
|
}
|
2025-03-16 23:26:45 +01:00
|
|
|
|
2025-03-28 11:06:24 +01:00
|
|
|
$this->cache->set("oembed_embedder_$provider_url$url", $ret, $cache_timeout);
|
2025-03-16 23:26:45 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$resp = new OembedResponse();
|
2025-03-17 12:47:08 +01:00
|
|
|
$resp->title = $ret['title'];
|
|
|
|
$resp->thumbnail_url = $ret['thumbnail_url'];
|
2025-03-28 11:06:24 +01:00
|
|
|
return $resp;
|
2025-03-16 23:26:45 +01:00
|
|
|
}
|
|
|
|
}
|