Skip to content

Commit f05857f

Browse files
committed
Reintroduce Adapter layer for file system / http abstraction
1 parent 4e7cbb0 commit f05857f

File tree

8 files changed

+145
-55
lines changed

8 files changed

+145
-55
lines changed

UPGRADE-6.0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
Several major changes in version 6.0:
44
- Requires PHP 8.1
55
- The factory has been removed. Use `new` to construct your FeedIO instance: `new \FeedIo\FeedIo($client, $logger)`
6-
- Guzzle comes no longer bundled with a default HTTP Client, but uses HTTPlug instead. To continue using Guzzle, please require `php-http/guzzle7-adapter`.
6+
- Feed IO comes no longer bundled with a default HTTP Client, but uses HTTPlug instead. To continue using Guzzle, please require `php-http/guzzle7-adapter`.

src/FeedIo/Adapter/ClientFactory.php

Lines changed: 0 additions & 14 deletions
This file was deleted.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FeedIo\Adapter\FileSystem;
6+
7+
use DateTime;
8+
use FeedIo\Adapter\ClientInterface;
9+
use FeedIo\Adapter\NotFoundException;
10+
use FeedIo\Adapter\ResponseInterface;
11+
12+
/**
13+
* Filesystem client
14+
*/
15+
class Client implements ClientInterface
16+
{
17+
/**
18+
* @param string $path
19+
* @param \DateTime $modifiedSince
20+
* @return \FeedIo\Adapter\ResponseInterface
21+
*@throws \FeedIo\Adapter\NotFoundException
22+
*/
23+
public function getResponse(string $path, DateTime $modifiedSince = null): ResponseInterface
24+
{
25+
if (file_exists($path)) {
26+
return new Response(
27+
file_get_contents($path),
28+
new DateTime('@'.filemtime($path))
29+
);
30+
}
31+
32+
throw new NotFoundException();
33+
}
34+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace FeedIo\Adapter\FileSystem;
6+
7+
use DateTime;
8+
use FeedIo\Adapter\ResponseInterface;
9+
10+
class Response implements ResponseInterface
11+
{
12+
public function __construct(
13+
protected string $fileContent,
14+
protected DateTime $lastModified
15+
) {
16+
}
17+
18+
/**
19+
* @return float
20+
*/
21+
public function getDuration(): float
22+
{
23+
return 0;
24+
}
25+
26+
/**
27+
* @return int
28+
*/
29+
public function getStatusCode(): int
30+
{
31+
return 0;
32+
}
33+
34+
/**
35+
* @return boolean
36+
*/
37+
public function isModified(): bool
38+
{
39+
return true;
40+
}
41+
42+
/**
43+
* @return string|null
44+
*/
45+
public function getBody(): ?string
46+
{
47+
return $this->fileContent;
48+
}
49+
50+
/**
51+
* @return iterable
52+
*/
53+
public function getHeaders(): iterable
54+
{
55+
return [];
56+
}
57+
58+
/**
59+
* @param string $name
60+
* @return iterable
61+
*/
62+
public function getHeader(string $name): iterable
63+
{
64+
return [];
65+
}
66+
67+
/**
68+
* @return DateTime|null
69+
*/
70+
public function getLastModified(): ?DateTime
71+
{
72+
return $this->lastModified;
73+
}
74+
}
Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@
22

33
declare(strict_types=1);
44

5-
namespace FeedIo\Adapter;
5+
namespace FeedIo\Adapter\Http;
66

77
use DateTime;
8+
use FeedIo\Adapter\ClientInterface;
9+
use FeedIo\Adapter\NotFoundException;
10+
use FeedIo\Adapter\ResponseInterface;
11+
use FeedIo\Adapter\ServerErrorException;
812
use Nyholm\Psr7\Request;
913
use Psr\Http\Client\ClientExceptionInterface;
1014
use Psr\Http\Client\ClientInterface as PsrClientInterface;
1115

1216
class Client implements ClientInterface
1317
{
14-
public function __construct(private PsrClientInterface $client)
18+
public function __construct(private readonly PsrClientInterface $client)
1519
{
1620
}
1721

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,15 @@
22

33
declare(strict_types=1);
44

5-
namespace FeedIo\Adapter;
5+
namespace FeedIo\Adapter\Http;
66

77
use DateTime;
8+
use FeedIo\Adapter\ResponseInterface;
89
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;
910

11+
/**
12+
* HTTP Response
13+
*/
1014
class Response implements ResponseInterface
1115
{
1216
public const HTTP_LAST_MODIFIED = 'Last-Modified';
@@ -37,7 +41,7 @@ public function isModified(): bool
3741
public function getBody(): ?string
3842
{
3943
if (is_null($this->body)) {
40-
$this->body = (string)$this->psrResponse->getBody();
44+
$this->body = $this->psrResponse->getBody()->getContents();
4145
}
4246

4347
return $this->body;

src/FeedIo/FeedIo.php

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@
55
namespace FeedIo;
66

77
use DateTime;
8-
use FeedIo\Adapter\ClientInterface as AdapterClientInterface;
9-
use FeedIo\Adapter\ClientFactory;
8+
use FeedIo\Adapter\ClientInterface;
109
use FeedIo\Http\ResponseBuilder;
1110
use FeedIo\Reader\Result;
1211
use FeedIo\Rule\DateTimeBuilderInterface;
13-
use Psr\Http\Client\ClientInterface;
1412
use Psr\Http\Message\ResponseInterface;
1513
use Psr\Log\LoggerInterface;
1614
use Psr\Log\NullLogger;
@@ -65,19 +63,16 @@
6563
*/
6664
class FeedIo
6765
{
68-
protected AdapterClientInterface $client;
6966
protected Reader $reader;
7067

7168
public function __construct(
72-
?ClientInterface $client = null,
73-
protected LoggerInterface $logger = new NullLogger(),
69+
protected ?ClientInterface $client = null,
70+
protected LoggerInterface $logger = new NullLogger(),
7471
protected ?SpecificationInterface $specification = null,
75-
ClientFactory $factory = new ClientFactory(),
7672
) {
7773
if (is_null($client)) {
78-
throw new \Exception('You must provide a PSR18-compliant HTTP client');
74+
throw new \Exception('You must provide an instance of FeedIo\Adapter\ClientInterface');
7975
}
80-
$this->client = $factory->create($client);
8176
if (is_null($this->specification)) {
8277
$this->specification = new Specification($this->logger);
8378
}

tests/FeedIo/FeedIoTest.php

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
namespace FeedIo;
44

5-
use FeedIo\Adapter\ClientFactory;
5+
use FeedIo\Adapter\Http\Client;
66
use Nyholm\Psr7\Response;
77
use Nyholm\Psr7\Stream;
88
use PHPUnit\Framework\TestCase;
99
use Psr\Http\Client\ClientInterface;
10-
use Psr\Http\Message\StreamInterface;
1110

1211
/**
1312
* Generated by PHPUnit_SkeletonGenerator on 2015-02-23 at 20:31:12.
@@ -27,49 +26,45 @@ protected function setUp(): void
2726
{
2827
$html = file_get_contents(__DIR__ ."/../samples/expected-atom.xml");
2928

30-
$adapterClient = $this->getMockForAbstractClass('\FeedIo\Adapter\ClientInterface');
31-
$clientFactory = $this->createMock(ClientFactory::class);
32-
$clientFactory->expects($this->once())->method('create')->willReturn($adapterClient);
29+
$client = $this->createMock(ClientInterface::class);
30+
$adapterClient = new Client($client);
3331

3432
$stream = $this->createMock(Stream::class);
3533
$stream->expects($this->any())->method('getContents')->willReturn($html);
3634

3735
$psrResponse = $this->createMock(Response::class);
3836
$psrResponse->expects($this->any())->method('getBody')->willReturn($stream);
3937
$psrResponse->expects($this->any())->method('getStatusCode')->willReturn(200);
40-
41-
$client = $this->createMock(ClientInterface::class);
4238
$client->method('sendRequest')->willReturn($psrResponse);
4339

4440
$adapterResponse = $this->createMock('FeedIo\Adapter\ResponseInterface');
4541
$adapterResponse->expects($this->any())->method('isModified')->willReturn(true);
4642
$adapterResponse->expects($this->any())->method('getBody')->willReturn($html);
4743
$adapterResponse->expects($this->any())->method('getLastModified')->willReturn(new \DateTime());
48-
$adapterClient->expects($this->any())->method('getResponse')->willReturn($adapterResponse);
4944

5045
$logger = new \Psr\Log\NullLogger();
5146

52-
$this->object = new FeedIo($client, $logger, new Specification($logger), $clientFactory);
47+
$this->object = new FeedIo($adapterClient, $logger, new Specification($logger));
5348
}
5449

5550
/**
56-
* @covers FeedIo\FeedIo::__construct
57-
* @covers FeedIo\FeedIo::loadCommonStandards
51+
* @covers \FeedIo\FeedIo::__construct
52+
* @covers \FeedIo\FeedIo::loadCommonStandards
5853
*/
5954
public function testConstruct()
6055
{
61-
$client = $this->getMockForAbstractClass(ClientInterface::class);
62-
$feedIo = new FeedIo($client, new \Psr\Log\NullLogger());
56+
$client = $this->createMock(ClientInterface::class);
57+
$adapterClient = new Client($client);
58+
$feedIo = new FeedIo($adapterClient, new \Psr\Log\NullLogger());
6359
$this->assertInstanceOf('\FeedIo\Reader', $feedIo->getReader());
6460
}
6561

6662
public function testDiscovery()
6763
{
6864
$html = file_get_contents(__DIR__ ."/../samples/discovery.html");
6965

70-
$adapterClient = $this->getMockForAbstractClass('\FeedIo\Adapter\ClientInterface');
71-
$clientFactory = $this->createMock(ClientFactory::class);
72-
$clientFactory->expects($this->once())->method('create')->willReturn($adapterClient);
66+
$client = $this->createMock(ClientInterface::class);
67+
$adapterClient = new Client($client);
7368

7469
$stream = $this->createMock(Stream::class);
7570
$stream->expects($this->any())->method('getContents')->willReturn($html);
@@ -78,14 +73,12 @@ public function testDiscovery()
7873
$psrResponse->method('getBody')->willReturn($stream);
7974
$psrResponse->method('getStatusCode')->willReturn(200);
8075

81-
$client = $this->createMock(ClientInterface::class);
8276
$client->method('sendRequest')->willReturn($psrResponse);
8377

8478
$adapterResponse = $this->createMock('FeedIo\Adapter\ResponseInterface');
8579
$adapterResponse->expects($this->any())->method('getBody')->willReturn($html);
86-
$adapterClient->expects($this->any())->method('getResponse')->willReturn($adapterResponse);
8780

88-
$feedIo = new FeedIo($client, new \Psr\Log\NullLogger(), null, $clientFactory);
81+
$feedIo = new FeedIo($adapterClient, new \Psr\Log\NullLogger(), null);
8982
$urls = $feedIo->discover('https://example.org/feed');
9083

9184
$this->assertCount(2, $urls);
@@ -99,15 +92,15 @@ public function testWithModifiedSince()
9992
}
10093

10194
/**
102-
* @covers FeedIo\FeedIo::getDateTimeBuilder
95+
* @covers \FeedIo\FeedIo::getDateTimeBuilder
10396
*/
10497
public function testGetDateTimeBuilder()
10598
{
10699
$this->assertInstanceOf('\FeedIo\Rule\DateTimeBuilder', $this->object->getDateTimeBuilder());
107100
}
108101

109102
/**
110-
* @covers FeedIo\FeedIo::getReader
103+
* @covers \FeedIo\FeedIo::getReader
111104
*/
112105
public function testGetReader()
113106
{
@@ -116,7 +109,7 @@ public function testGetReader()
116109

117110

118111
/**
119-
* @covers FeedIo\FeedIo::read
112+
* @covers \FeedIo\FeedIo::read
120113
*/
121114
public function testRead()
122115
{
@@ -126,8 +119,8 @@ public function testRead()
126119
}
127120

128121
/**
129-
* @covers FeedIo\FeedIo::format
130-
* @covers FeedIo\FeedIo::logAction
122+
* @covers \FeedIo\FeedIo::format
123+
* @covers \FeedIo\FeedIo::logAction
131124
*/
132125
public function testFormat()
133126
{
@@ -139,7 +132,7 @@ public function testFormat()
139132
}
140133

141134
/**
142-
* @covers FeedIo\FeedIo::toRss
135+
* @covers \FeedIo\FeedIo::toRss
143136
*/
144137
public function testToRss()
145138
{
@@ -150,7 +143,7 @@ public function testToRss()
150143
}
151144

152145
/**
153-
* @covers FeedIo\FeedIo::toAtom
146+
* @covers \FeedIo\FeedIo::toAtom
154147
*/
155148
public function testToAtom()
156149
{
@@ -161,7 +154,7 @@ public function testToAtom()
161154
}
162155

163156
/**
164-
* @covers FeedIo\FeedIo::toJson
157+
* @covers \FeedIo\FeedIo::toJson
165158
*/
166159
public function testToJson()
167160
{

0 commit comments

Comments
 (0)