Completed
Push — master ( 4c7da2...64af60 )
by Alex
02:34 queued 46s
created

FeedIo   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 312
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 13

Test Coverage

Coverage 98.86%

Importance

Changes 0
Metric Value
wmc 30
c 0
b 0
f 0
lcom 1
cbo 13
dl 0
loc 312
ccs 87
cts 88
cp 0.9886
rs 10

23 Methods

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