diff --git a/extension_add_support_to_live_photo.php b/extension_add_support_to_live_photo.php new file mode 100644 index 0000000..6fc74a9 --- /dev/null +++ b/extension_add_support_to_live_photo.php @@ -0,0 +1,280 @@ +registerHook('entry_before_display', [self::class, 'content_modification_hook']); + $this->registerHook('entry_before_insert', [self::class, 'image_upload_hook']); + // Defaults + $save = false; + if (is_null(FreshRSS_Context::userConf()->image_cache_url)) { + FreshRSS_Context::userConf()->image_cache_url = self::CACHE_URL; + $save = true; + } + if (is_null(FreshRSS_Context::userConf()->image_cache_post_url)) { + FreshRSS_Context::userConf()->image_cache_post_url = self::CACHE_POST_URL; + $save = true; + } + if (is_null(FreshRSS_Context::userConf()->image_cache_access_token)) { + FreshRSS_Context::userConf()->image_cache_access_token = self::CACHE_ACCESS_TOKEN; + $save = true; + } + if (is_null(FreshRSS_Context::userConf()->image_cache_post_enabled)) { + FreshRSS_Context::userConf()->image_cache_post_enabled = self::CACHE_POST_ENABLED; + $save = true; + } + if ($save) { + FreshRSS_Context::userConf()->save(); + } + } + + #[\Override] + public function handleConfigureAction(): void + { + $this->registerTranslates(); + if (Minz_Request::isPost()) { + FreshRSS_Context::userConf()->image_cache_url = Minz_Request::paramString('image_cache_url'); + FreshRSS_Context::userConf()->image_cache_post_url = Minz_Request::paramString('image_cache_post_url'); + FreshRSS_Context::userConf()->image_cache_access_token = Minz_Request::paramString('image_cache_access_token'); + FreshRSS_Context::userConf()->image_cache_post_enabled = Minz_Request::paramString('image_cache_post_enabled'); + FreshRSS_Context::userConf()->save(); + } + } + + public static function curlPostRequest(string $url, array $data): bool + { + $data = json_encode($data); + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $url); + curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST"); + curl_setopt($curl, CURLOPT_POSTFIELDS, $data); + curl_setopt($curl, CURLOPT_HEADER, true); + curl_setopt($curl, CURLOPT_HTTPHEADER, array( + "Content-Type: application/json;charset='utf-8'", + 'Content-Length: ' . strlen($data), + "Accept: application/json") + ); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5); + curl_setopt($curl, CURLOPT_TIMEOUT, 10); + $output = curl_exec($curl); + curl_close($curl); + if ($output === false) { + return false; + } + return true; + } + + public static function is_remote_url(string $url): bool + { + return strcmp(substr(strtolower($url), 0, 5), "data:") != 0; + } + + public static function send_proactive_cache_request(string $url): bool + { + if (FreshRSS_Context::userConf()->image_cache_post_enabled && self::is_remote_url($url)) { + $post_url = FreshRSS_Context::userConf()->image_cache_post_url; + return self::curlPostRequest($post_url, array("access_token" => FreshRSS_Context::userConf()->image_cache_access_token, "url" => $url)); + } + return false; + } + + public static function getCacheImageUri(string $url): string + { + if (!self::is_remote_url($url)) { + return $url; + } + $url = rawurlencode($url); + return FreshRSS_Context::userConf()->image_cache_url . $url; + } + + /** + * 仅缓存资源(发送缓存请求),不替换 URL + */ + public static function cache_images(string $content): string + { + if (empty($content)) { + return $content; + } + $doc = new DOMDocument(); + libxml_use_internal_errors(true); + $encoding = mb_detect_encoding($content); + $doc->loadHTML(''.$content); + + // 处理 标签 + $imgs = $doc->getElementsByTagName('img'); + foreach ($imgs as $img) { + if ($img->hasAttribute('src')) { + self::send_proactive_cache_request($img->getAttribute('src')); + } + if ($img->hasAttribute('srcset')) { + preg_replace_callback('/(?:([^\s,]+)(\s*(?:\s+\d+[wx])(?:,\s*)?))/', + function (array $matches): string { + self::send_proactive_cache_request($matches[1]); + return ''; + }, + $img->getAttribute('srcset')); + } + // 处理 Live Photo + if ($img->hasAttribute('data-livephoto')) { + self::send_proactive_cache_request($img->getAttribute('data-livephoto')); + } + } + + // 处理