Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion xExtension-GridView/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Your grid view preference is saved locally and persists across sessions.

## Requirements

- FreshRSS 1.20.0 or later
- FreshRSS 1.28.0 or later

## Responsive Breakpoints

Expand Down
33 changes: 10 additions & 23 deletions xExtension-GridView/extension.php
Original file line number Diff line number Diff line change
Expand Up @@ -430,43 +430,30 @@ private function ensureThumbnail(FreshRSS_Entry $entry, bool $persist = false):
/**
* Fetch a URL and extract the og:image meta tag.
*
* @param string $url The article URL to fetch
* @param non-empty-string $url The article URL to fetch
* @return string|null The og:image URL or null if not found
*/
private function extractOgImage(string $url): ?string {
$ctx = stream_context_create([
'http' => [
'timeout' => 5,
'method' => 'GET',
'header' => "User-Agent: FreshRSS/GridView\r\n",
'follow_location' => 1,
'max_redirects' => 3,
'ignore_errors' => true,
],
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
],
]);

// Only fetch the first 50 KB — og:image is in <head>
$html = @file_get_contents($url, false, $ctx, 0, 50000);
if ($html === false || $html === '') {
// Use the FreshRSS HTTP client, as FreshRSS 1.30+ disables the http(s) stream wrappers
['body' => $html, 'effective_url' => $effectiveUrl, 'fail' => $fail] = FreshRSS_http_Util::httpGet($url,
cachePath: CACHE_PATH . '/' . sha1($url) . '.html', type: 'html', attributes: ['timeout' => 5]);
if ($fail || $html === '') {
return null;
}
$pageUrl = $effectiveUrl ?: $url;

// Try og:image first, then twitter:image (both attribute orderings)
if (preg_match('/<meta\s[^>]*property=["\']og:image["\'][^>]*content=["\']([^"\']+)["\']/i', $html, $matches)) {
return $this->normalizeImageUrl($matches[1], $url);
return $this->normalizeImageUrl($matches[1], $pageUrl);
}
if (preg_match('/<meta\s[^>]*content=["\']([^"\']+)["\'][^>]*property=["\']og:image["\']/i', $html, $matches)) {
return $this->normalizeImageUrl($matches[1], $url);
return $this->normalizeImageUrl($matches[1], $pageUrl);
}
if (preg_match('/<meta\s[^>]*name=["\']twitter:image["\'][^>]*content=["\']([^"\']+)["\']/i', $html, $matches)) {
return $this->normalizeImageUrl($matches[1], $url);
return $this->normalizeImageUrl($matches[1], $pageUrl);
}
if (preg_match('/<meta\s[^>]*content=["\']([^"\']+)["\'][^>]*name=["\']twitter:image["\']/i', $html, $matches)) {
return $this->normalizeImageUrl($matches[1], $url);
return $this->normalizeImageUrl($matches[1], $pageUrl);
}

return null;
Expand Down
4 changes: 2 additions & 2 deletions xExtension-GridView/metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"name": "Grid View",
"author": "Marius Stroe <https://github.com/mstroe>",
"description": "A grid/card view for displaying feeds with images, configurable 2-4 columns, FreshRSS native share integration, and browser reader mode support",
"version": "1.1.1",
"version": "1.1.2",
"entrypoint": "GridView",
"type": "user",
"compatibility": "1.25.0"
"compatibility": "1.28.0"
}