Completed
Pull Request — project/php-7 (#129)
by Alex
01:48
created

Reader   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 145
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 82.61%

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 8
dl 0
loc 145
ccs 38
cts 46
cp 0.8261
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A addParser() 0 7 1
A parseDocument() 0 7 1
A read() 0 19 3
A handleResponse() 0 12 2
A getAccurateParser() 0 12 3
A addFilter() 0 8 2
A resetFilters() 0 8 2
1
<?php
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\ParserAbstract;
14
use FeedIo\Adapter\ClientInterface;
15
use FeedIo\Adapter\ResponseInterface;
16
use FeedIo\Reader\Document;
17
use FeedIo\Reader\ReadErrorException;
18
use FeedIo\Reader\Result;
19
use FeedIo\Reader\NoAccurateParserException;
20
use Psr\Log\LoggerInterface;
21
22
/**
23
 * Consumes feeds and return corresponding Result instances
24
 *
25
 * Depends on :
26
 *  - FeedIo\Adapter\ClientInterface
27
 *  - Psr\Log\LoggerInterface
28
 *
29
 * A Reader instance MUST have at least one parser added with the addParser() method to read feeds
30
 * It will throw a NoAccurateParserException if it cannot find a suitable parser for the feed.
31
 */
32
class Reader
33
{
34
    /**
35
     * @var \FeedIo\Adapter\ClientInterface;
36
     */
37
    protected $client;
38
39
    /**
40
     * @var \Psr\Log\LoggerInterface
41
     */
42
    protected $logger;
43
44
    /**
45
     * @var array
46
     */
47
    protected $parsers = array();
48
49
    /**
50
     * @param ClientInterface $client
51
     * @param LoggerInterface $logger
52
     */
53 12
    public function __construct(ClientInterface $client, LoggerInterface $logger)
54
    {
55 12
        $this->client = $client;
56 12
        $this->logger = $logger;
57 12
    }
58
59
    /**
60
     * @param  Parser $parser
61
     * @return $this
62
     */
63 11
    public function addParser(ParserAbstract $parser)
64
    {
65 11
        $this->logger->debug("new parser added : ".get_class($parser->getStandard()));
66 11
        $this->parsers[] = $parser;
67
68 11
        return $this;
69
    }
70
71
    /**
72
     * adds a filter to every parsers
73
     *
74
     * @param \FeedIo\FilterInterface $filter
75
     * @return $this
76
     */
77
    public function addFilter(FilterInterface $filter)
78
    {
79
        foreach ($this->parsers as $parser) {
80
            $parser->addFilter($filter);
81
        }
82
83
        return $this;
84
    }
85
86
    /**
87
     * Reset filters on every parsers
88
     * @return $this
89
     */
90
    public function resetFilters()
91
    {
92
        foreach ($this->parsers as $parser) {
93
            $parser->resetFilters();
94
        }
95
96
        return $this;
97
    }
98
99
    /**
100
     * @param $url
101
     * @param  FeedInterface         $feed
102
     * @param  \DateTime             $modifiedSince
103
     * @return \FeedIo\Reader\Result
104
     * @throws ReadErrorException
105
     */
106 3
    public function read($url, FeedInterface $feed, \DateTime $modifiedSince = null)
107
    {
108 3
        $this->logger->debug("start reading {$url}");
109 3
        if (is_null($modifiedSince)) {
110 2
            $this->logger->notice("no 'modifiedSince' parameter given, setting it to 01/01/1970");
111 2
            $modifiedSince = new \DateTime('@0');
112
        }
113
114
        try {
115 3
            $this->logger->info("hitting {$url}");
116 3
            $response = $this->client->getResponse($url, $modifiedSince);
117 2
            $document = $this->handleResponse($response, $feed);
118
119 2
            return new Result($document, $feed, $modifiedSince, $response, $url);
120 1
        } catch (\Exception $e) {
121 1
            $this->logger->warning("{$url} read error : {$e->getMessage()}");
122 1
            throw new ReadErrorException($e);
123
        }
124
    }
125
126
    /**
127
     * @param  ResponseInterface     $response
128
     * @param  FeedInterface         $feed
129
     * @return Document
130
     */
131 2
    public function handleResponse(ResponseInterface $response, FeedInterface $feed)
132
    {
133 2
        $this->logger->debug("response ok, now turning it into a document");
134 2
        $document = new Document($response->getBody());
135
136 2
        if ($response->isModified()) {
137 1
            $this->logger->info("the stream is modified, parsing it");
138 1
            $this->parseDocument($document, $feed);
139
        }
140
141 2
        return $document;
142
    }
143
144
    /**
145
     * @param Document $document
146
     * @param FeedInterface $feed
147
     * @return FeedInterface
148
     * @throws Parser\UnsupportedFormatException
149
     * @throws Reader\NoAccurateParserException
150
     */
151 2
    public function parseDocument(Document $document, FeedInterface $feed)
152
    {
153 2
        $parser = $this->getAccurateParser($document);
154 2
        $this->logger->debug("accurate parser : ".get_class($parser));
155
156 2
        return $parser->parse($document, $feed);
157
    }
158
159
    /**
160
     * @param  Document                     $document
161
     * @return ParserAbstract
162
     * @throws Reader\NoAccurateParserException
163
     */
164 4
    public function getAccurateParser(Document $document)
165
    {
166 4
        foreach ($this->parsers as $parser) {
167 3
            if ($parser->getStandard()->canHandle($document)) {
168 3
                return $parser;
169
            }
170
        }
171
172 1
        $message = 'No parser can handle this stream';
173 1
        $this->logger->error($message);
174 1
        throw new NoAccurateParserException($message);
175
    }
176
}
177