Completed
Push — issue/127 ( 820451...719f45 )
by Alex
03:15
created

FeedIo::getFixerSet()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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