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
23 changes: 22 additions & 1 deletion src/SimplePie.php
Original file line number Diff line number Diff line change
Expand Up @@ -3224,6 +3224,28 @@ public function get_longitude()
return null;
}

/**
* Get the feed icon's URL
*
* Returns favicon-like feed artwork only.
*
* Uses `<atom:icon>`, or RSS 2.0 `<image><url>` (only if square).
*
* @return string|null
*/
public function get_icon_url()
{
if ($return = $this->get_channel_tags(self::NAMESPACE_ATOM_10, 'icon')) {
return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
} elseif (($return = $this->get_image_tags(self::NAMESPACE_RSS_20, 'url')) &&
($this->get_image_width() ?? -2) === ($this->get_image_height() ?? -3)) {
// Use only if the image is square, otherwise it is likely a banner and not an icon
return $this->sanitize($return[0]['data'], self::CONSTRUCT_IRI, $this->get_base($return[0]));
}

return null;
}

/**
* Get the feed logo's title
*
Expand Down Expand Up @@ -3280,7 +3302,6 @@ public function get_image_url()
return null;
}


/**
* Get the feed logo's link
*
Expand Down
99 changes: 99 additions & 0 deletions tests/Unit/SimplePieTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1899,6 +1899,105 @@ public function test_get_image_url(string $data, string $expected): void
self::assertSame($expected, $feed->get_image_url());
}

/**
* @return array<array{string, string|null}>
*/
public static function getIconUrlDataProvider(): array
{
return [
'Test Atom 1.0 Icon' => [
<<<XML
<feed xmlns="http://www.w3.org/2005/Atom">
<icon>http://example.com/icon.png</icon>
</feed>
XML
,
'http://example.com/icon.png',
],
'Test Atom 1.0 Icon priority over RSS 2.0 image' => [
<<<XML
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<atom:icon>http://example.com/icon.png</atom:icon>
<image>
<url>http://example.com/image.png</url>
<width>32</width>
<height>32</height>
</image>
</channel>
</rss>
XML
,
'http://example.com/icon.png',
],
'Test Atom 1.0 Logo is not an icon' => [
<<<XML
<feed xmlns="http://www.w3.org/2005/Atom">
<logo>http://example.com/logo.png</logo>
</feed>
XML
,
null,
],
'Test RSS 2.0 Square image' => [
<<<XML
<rss version="2.0">
<channel>
<image>
<url>http://example.com/icon.png</url>
<width>32</width>
<height>32</height>
</image>
</channel>
</rss>
XML
,
'http://example.com/icon.png',
],
'Test RSS 2.0 Default image not square' => [
<<<XML
<rss version="2.0">
<channel>
<image>
<url>http://example.com/image.png</url>
</image>
</channel>
</rss>
XML
,
null,
],
'Test RSS 2.0 Non Square Image' => [
<<<XML
<rss version="2.0">
<channel>
<image>
<url>http://example.com/image.png</url>
<width>32</width>
<height>31</height>
</image>
</channel>
</rss>
XML
,
null,
],
];
}

/**
* @dataProvider getIconUrlDataProvider
*/
public function test_get_icon_url(string $data, ?string $expected): void
{
$feed = new SimplePie();
$feed->set_raw_data($data);
$feed->enable_cache(false);
$feed->init();

self::assertSame($expected, $feed->get_icon_url());
}

/**
* @return array<array{string, int|null}>
*/
Expand Down
Loading