Completed
Push — release/4.1 ( 25f57b...51f4ed )
by Alex
01:17
created

FeedIo::getPsrResponse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 4
crap 1
1
<?php declare(strict_types=1);
2
/*
3
 * This file is part of the feed-io package.
4
 *
5
 * (c) Alexandre Debril <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace FeedIo;
12
13
use FeedIo\Filter\ModifiedSince;
14
use FeedIo\Reader\Result;
15
use FeedIo\Reader\FixerSet;
16
use FeedIo\Reader\FixerAbstract;
17
use FeedIo\Rule\DateTimeBuilder;
18
use FeedIo\Adapter\ClientInterface;
19
use FeedIo\Standard\Loader;
20
use FeedIo\FeedInterface;
21
use Psr\Log\LoggerInterface;
22
use FeedIo\Http\ResponseBuilder;
23
use Psr\Http\Message\ResponseInterface;
24
25
/**
26
 * This class acts as a facade. It provides methods to access feed-io main features
27
 *
28
 * <code>
29
 *   // $client is a \FeedIo\Adapter\ClientInterface instance, $logger a \Psr\Log\LoggerInterface
30
 *   $feedIo = new FeedIo($client, $logger);
31
 *
32
 *   // read a feed. Output is a Result instance
33
 *   $result = $feedIo->read('http://somefeed.org/feed.rss');
34
 *
35
 *   // use the feed
36
 *   $feed = $result->getFeed();
37
 *   echo $feed->getTitle();
38
 *
39
 *   // and its items
40
 *   foreach ( $feed as $item ) {
41
 *       echo $item->getTitle();
42
 *       echo $item->getDescription();
43
 *   }
44
 *
45
 * </code>
46
 *
47
 * <code>
48
 *   // build the feed to publish
49
 *   $feed = new \FeedIo\Feed;
50
 *   $feed->setTitle('title');
51
 *   // ...
52
 *
53
 *   // add items to it
54
 *   $item = new \FeedIo\Feed\Item
55
 *   $item->setTitle('my great post');
56
 *
57
 *   // want to publish a media ? no problem
58
 *   $media = new \FeedIo\Feed\Item\Media
59
 *   $media->setUrl('http://yourdomain.tld/medias/some-podcast.mp3');
60
 *   $media->setType('audio/mpeg');
61
 *
62
 *   // add it to the item
63
 *   $item->addMedia($media);
64
 *
65
 *   // add the item to the feed (almost there)
66
 *   $feed->add($item);
67
 *
68
 *   // format it in atom
69
 *   $feedIo->toAtom($feed);
70
 * </code>
71
 *
72
 */
73
class FeedIo
74
{
75
76
    /**
77
     * @var \FeedIo\Reader
78
     */
79
    protected $reader;
80
81
    /**
82
     * @var \FeedIo\Rule\DateTimeBuilder
83
     */
84
    protected $dateTimeBuilder;
85
86
    /**
87
     * @var \Psr\Log\LoggerInterface
88
     */
89
    protected $logger;
90
91
    /**
92
     * @var array
93
     */
94
    protected $standards;
95
96
    /**
97
     * @var \FeedIo\Reader\FixerSet
98
     */
99
    protected $fixerSet;
100
101
    /**
102
     * @param \FeedIo\Adapter\ClientInterface $client
103
     * @param \Psr\Log\LoggerInterface        $logger
104
     */
105 9
    public function __construct(ClientInterface $client, LoggerInterface $logger)
106
    {
107 9
        $this->logger = $logger;
108 9
        $this->dateTimeBuilder = new DateTimeBuilder($logger);
109 9
        $this->setReader(new Reader($client, $logger));
110 9
        $this->loadCommonStandards();
111 9
        $this->loadFixerSet();
112 9
    }
113
114
    /**
115
     * Loads main standards (RSS, RDF, Atom) in current object's attributes
116
     *
117
     * @return FeedIo
118
     */
119 9
    protected function loadCommonStandards() : FeedIo
120
    {
121 9
        $standards = $this->getCommonStandards();
122 9
        foreach ($standards as $name => $standard) {
123 9
            $this->addStandard($name, $standard);
124
        }
125
126 9
        return $this;
127
    }
128
129
    /**
130
     * adds a filter to the reader
131
     *
132
     * @param \FeedIo\FilterInterface $filter
133
     * @return FeedIo
134
     */
135
    public function addFilter(FilterInterface $filter) : FeedIo
136
    {
137
        $this->getReader()->addFilter($filter);
138
139
        return $this;
140
    }
141
142
    /**
143
     * Returns main standards
144
     *
145
     * @return array
146
     */
147 9
    public function getCommonStandards() : array
148
    {
149 9
        $loader = new Loader();
150
151 9
        return $loader->getCommonStandards($this->getDateTimeBuilder());
152
    }
153
154
    /**
155
     * @param  string                   $name
156
     * @param  \FeedIo\StandardAbstract $standard
157
     * @return FeedIo
158
     */
159 9
    public function addStandard(string $name, StandardAbstract $standard) : FeedIo
160
    {
161 9
        $name = strtolower($name);
162 9
        $this->standards[$name] = $standard;
163 9
        $parser = $this->newParser($standard->getSyntaxFormat(), $standard);
164 9
        $this->reader->addParser($parser);
165
166 9
        return $this;
167
    }
168
169
    /**
170
     * @param string $format
171
     * @param StandardAbstract $standard
172
     * @return ParserAbstract
173
     */
174 8
    public function newParser(string $format, StandardAbstract $standard) : ParserAbstract
175
    {
176 8
        $reflection = new \ReflectionClass("FeedIo\\Parser\\{$format}Parser");
177
178 8
        if (! $reflection->isSubclassOf('FeedIo\ParserAbstract')) {
179
            throw new \InvalidArgumentException();
180
        }
181
182 8
        return $reflection->newInstanceArgs([$standard, $this->logger]);
183
    }
184
185
    /**
186
     * @return \FeedIo\Reader\FixerSet
187
     */
188 1
    public function getFixerSet() : FixerSet
189
    {
190 1
        return $this->fixerSet;
191
    }
192
193
    /**
194
     * @return FeedIo
195
     */
196 8
    protected function loadFixerSet() : FeedIo
197
    {
198 8
        $this->fixerSet = new FixerSet();
199 8
        $fixers = $this->getBaseFixers();
200
201 8
        foreach ($fixers as $fixer) {
202 8
            $this->addFixer($fixer);
203
        }
204
205 8
        return $this;
206
    }
207
208
    /**
209
     * @param  FixerAbstract $fixer
210
     * @return FeedIo
211
     */
212 8
    public function addFixer(FixerAbstract $fixer) : FeedIo
213
    {
214 8
        $fixer->setLogger($this->logger);
215 8
        $this->fixerSet->add($fixer);
216
217 8
        return $this;
218
    }
219
220
    /**
221
     * @return array
222
     */
223 8
    public function getBaseFixers() : array
224
    {
225
        return array(
226 8
            new Reader\Fixer\LastModified(),
227 8
            new Reader\Fixer\PublicId(),
228
        );
229
    }
230
231
    /**
232
     * @param array $formats
233
     * @return FeedIo
234
     */
235 1
    public function addDateFormats(array $formats) : FeedIo
236
    {
237 1
        foreach ($formats as $format) {
238 1
            $this->getDateTimeBuilder()->addDateFormat($format);
239
        }
240
241 1
        return $this;
242
    }
243
244
    /**
245
     * @return \FeedIo\Rule\DateTimeBuilder
246
     */
247 9
    public function getDateTimeBuilder() : DateTimeBuilder
248
    {
249 9
        return $this->dateTimeBuilder;
250
    }
251
252
    /**
253
     * @return \FeedIo\Reader
254
     */
255 1
    public function getReader() : Reader
256
    {
257 1
        return $this->reader;
258
    }
259
260
    /**
261
     * @param \FeedIo\Reader
262
     * @return FeedIo
263
     */
264 9
    public function setReader(Reader $reader) : FeedIo
265
    {
266 9
        $this->reader = $reader;
267
268 9
        return $this;
269
    }
270
271
    /**
272
     * @param  string                $url
273
     * @param  FeedInterface         $feed
274
     * @param  \DateTime             $modifiedSince
275
     * @return \FeedIo\Reader\Result
276
     */
277 1
    public function read(string $url, FeedInterface $feed = null, \DateTime $modifiedSince = null) : Result
278
    {
279 1
        if (is_null($feed)) {
280 1
            $feed = new Feed();
281
        }
282
283 1
        if ($modifiedSince instanceof \DateTime) {
284
            $this->addFilter(new ModifiedSince($modifiedSince));
285
        }
286
287 1
        $this->logAction($feed, "read access : $url into a feed instance");
288 1
        $result = $this->reader->read($url, $feed, $modifiedSince);
289
290 1
        $this->fixerSet->correct($result->getFeed());
291
292 1
        return $result;
293
    }
294
295
    /**
296
     * @param  string                $url
297
     * @param  \DateTime             $modifiedSince
298
     * @return \FeedIo\Reader\Result
299
     */
300 1
    public function readSince(string $url, \DateTime $modifiedSince) : Result
301
    {
302 1
        return $this->read($url, new Feed(), $modifiedSince);
303
    }
304
305
    /**
306
     * @return FeedIo
307
     */
308
    public function resetFilters() : FeedIo
309
    {
310
        $this->getReader()->resetFilters();
311
312
        return $this;
313
    }
314
315 1
    public function getPsrResponse(FeedInterface $feed, string $standard, int $maxAge = 600, bool $public = true) : ResponseInterface
316
    {
317 1
        $this->logAction($feed, "creating a PSR 7 Response in $standard format");
318
319 1
        $formatter = $this->getStandard($standard)->getFormatter();
320 1
        $responseBuilder = new ResponseBuilder($maxAge, $public);
321
322 1
        return $responseBuilder->createResponse($standard, $formatter, $feed);
323
    }
324
325
    /**
326
     * @param  FeedInterface $feed
327
     * @param  string        $standard Standard's name
328
     * @return string
329
     */
330 1
    public function format(FeedInterface $feed, string $standard) : string
331
    {
332 1
        $this->logAction($feed, "formatting a feed in $standard format");
333
334 1
        $formatter = $this->getStandard($standard)->getFormatter();
335
336 1
        return $formatter->toString($feed);
337
    }
338
339
    /**
340
     * @param  \FeedIo\FeedInterface $feed
341
     * @return string
342
     */
343 1
    public function toRss(FeedInterface $feed) : string
344
    {
345 1
        return $this->format($feed, 'rss');
346
    }
347
348
    /**
349
     * @param  \FeedIo\FeedInterface $feed
350
     * @return string
351
     */
352 1
    public function toAtom(FeedInterface $feed) : string
353
    {
354 1
        return $this->format($feed, 'atom');
355
    }
356
357
    /**
358
     * @param  \FeedIo\FeedInterface $feed
359
     * @return string
360
     */
361 1
    public function toJson(FeedInterface $feed) : string
362
    {
363 1
        return $this->format($feed, 'json');
364
    }
365
366
367
    /**
368
     * @param  string                   $name
369
     * @return \FeedIo\StandardAbstract
370
     * @throws \OutOfBoundsException
371
     */
372 3
    public function getStandard(string $name) : StandardAbstract
373
    {
374 3
        $name = strtolower($name);
375 3
        if (array_key_exists($name, $this->standards)) {
376 2
            return $this->standards[$name];
377
        }
378
379 1
        throw new \OutOfBoundsException("no standard found for $name");
380
    }
381
382
    /**
383
     * @param  \FeedIo\FeedInterface $feed
384
     * @param  string                $message
385
     * @return FeedIo
386
     */
387 2
    protected function logAction(FeedInterface $feed, string $message) : FeedIo
388
    {
389 2
        $class = get_class($feed);
390 2
        $this->logger->debug("$message (feed class : $class)");
391
392 2
        return $this;
393
    }
394
}
395