Skip to content

Commit ef5644a

Browse files
committed
Make feed discovery work with direct feed urls.
1 parent 4626a26 commit ef5644a

File tree

3 files changed

+54
-12
lines changed

3 files changed

+54
-12
lines changed

src/Service/FeedService.php

+31-11
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,25 @@ public function discoverFeeds(string $url): array
7373
// Fetch the URL
7474
$response = $this->fetchUrl($url);
7575

76-
$responseType = $response->getHeaderLine('Content-Type');
77-
// Must claim to be HTML.
78-
if (!str_contains($responseType, 'html')) {
76+
/** @var array<\App\Model\Entity\Feed> $feeds */
77+
$feeds = [];
78+
79+
$contentType = $this->getContentType($response);
80+
$feedTypes = ['application/atom+xml', 'application/xml', 'text/xml', 'application/rss', 'application/rss+xml'];
81+
82+
// Feed URL provided
83+
if (in_array($contentType, $feedTypes)) {
84+
$feeds[] = new Feed([
85+
'default_alias' => $url,
86+
'url' => $url,
87+
'favicon_url' => '',
88+
]);
89+
90+
return $feeds;
91+
}
92+
93+
// If we didn't get a feed URL, or an HTML page abort.
94+
if ($contentType != 'text/html') {
7995
throw new RuntimeException('That URL is not an HTML page. No feed could be found.');
8096
}
8197
try {
@@ -93,9 +109,6 @@ public function discoverFeeds(string $url): array
93109
// No user/pass support yet.
94110
$uri = new Uri($url);
95111

96-
/** @var array<\App\Model\Entity\Feed> $feeds */
97-
$feeds = [];
98-
99112
// parse the HTML page looking for link elements
100113
$xpath = new DOMXPath($dom);
101114

@@ -172,6 +185,17 @@ protected function findFavicon(DOMXPath $xpath): ?string
172185
return null;
173186
}
174187

188+
protected function getContentType(Response $res): string
189+
{
190+
$contentType = $res->getHeaderLine('Content-Type');
191+
$colonPos = strpos($contentType, ';');
192+
if ($colonPos !== false) {
193+
$contentType = substr($contentType, 0, $colonPos);
194+
}
195+
196+
return $contentType;
197+
}
198+
175199
/**
176200
* Import new FeedItems for all the unique items in a feed's current response
177201
*/
@@ -196,11 +220,7 @@ public function refreshFeed(Feed $feed): void
196220

197221
protected function parseResponse(Response $res, Feed $feed): array
198222
{
199-
$contentType = $res->getHeaderLine('Content-Type');
200-
$colonPos = strpos($contentType, ';');
201-
if ($colonPos !== false) {
202-
$contentType = substr($contentType, 0, $colonPos);
203-
}
223+
$contentType = $this->getContentType($res);
204224
$body = (string)$res->getBody();
205225
// No items in an empty response.
206226
if (!$body) {

templates/FeedSubscriptions/discover.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
<?php if ($this->request->getData('url')) : ?>
4848
<?php if (count($feeds) == 0) : ?>
4949
<div class="discover-feeds">
50-
<p class="empty">No feeds. Provide a URL above to get started.</p>
50+
<p class="empty">No feeds were found. Provide a URL above to get started.</p>
5151
</div>
5252
<?php endif; ?>
5353
<?php endif; ?>

tests/TestCase/Service/FeedServiceTest.php

+22
Original file line numberDiff line numberDiff line change
@@ -359,4 +359,26 @@ public function testDiscoverFeedAtom(): void
359359
$this->assertEquals('Releases - markstory/asset_compress', $feed->default_alias);
360360
$this->assertEquals('https://github.com/markstory/asset_compress/releases.atom', $feed->url);
361361
}
362+
363+
public function testDiscoverFeedDirectFeedUrl(): void
364+
{
365+
// Feed discovery should work if a direct URL was provided.
366+
$url = 'https://example.org/feed';
367+
$res = $this->newClientResponse(
368+
200,
369+
['Content-Type: application/rss; charset=utf-8'],
370+
$this->readFeedFixture('mark-story-com.rss')
371+
);
372+
$this->mockClientGet($url, $res);
373+
$client = new Client();
374+
375+
$service = new FeedService($client, $this->cleaner);
376+
$feeds = $service->discoverFeeds($url);
377+
$this->assertCount(1, $feeds);
378+
$feed = $feeds[0];
379+
$this->assertInstanceOf(Feed::class, $feed);
380+
$this->assertEquals('https://example.org/feed', $feed->url);
381+
$this->assertEquals($url, $feed->default_alias);
382+
$this->assertEquals('', $feed->favicon_url);
383+
}
362384
}

0 commit comments

Comments
 (0)