Completed
Push — issue/70 ( 39b47c )
by Alex
03:11
created

Reader::resetFilters()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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