This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
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\Rule\DateTimeBuilderInterface; |
||
19 | use FeedIo\Adapter\ClientInterface; |
||
20 | use FeedIo\Standard\Loader; |
||
21 | use FeedIo\Async\Reader as AsyncReader; |
||
22 | use FeedIo\Async\CallbackInterface; |
||
23 | use FeedIo\FeedInterface; |
||
24 | use Psr\Log\LoggerInterface; |
||
25 | use FeedIo\Http\ResponseBuilder; |
||
26 | use Psr\Http\Message\ResponseInterface; |
||
27 | |||
28 | /** |
||
29 | * This class acts as a facade. It provides methods to access feed-io main features |
||
30 | * |
||
31 | * <code> |
||
32 | * // $client is a \FeedIo\Adapter\ClientInterface instance, $logger a \Psr\Log\LoggerInterface |
||
33 | * $feedIo = new FeedIo($client, $logger); |
||
34 | * |
||
35 | * // read a feed. Output is a Result instance |
||
36 | * $result = $feedIo->read('http://somefeed.org/feed.rss'); |
||
37 | * |
||
38 | * // use the feed |
||
39 | * $feed = $result->getFeed(); |
||
40 | * echo $feed->getTitle(); |
||
41 | * |
||
42 | * // and its items |
||
43 | * foreach ( $feed as $item ) { |
||
44 | * echo $item->getTitle(); |
||
45 | * echo $item->getDescription(); |
||
46 | * } |
||
47 | * |
||
48 | * </code> |
||
49 | * |
||
50 | * <code> |
||
51 | * // build the feed to publish |
||
52 | * $feed = new \FeedIo\Feed; |
||
53 | * $feed->setTitle('title'); |
||
54 | * // ... |
||
55 | * |
||
56 | * // add items to it |
||
57 | * $item = new \FeedIo\Feed\Item |
||
58 | * $item->setTitle('my great post'); |
||
59 | * |
||
60 | * // want to publish a media ? no problem |
||
61 | * $media = new \FeedIo\Feed\Item\Media |
||
62 | * $media->setUrl('http://yourdomain.tld/medias/some-podcast.mp3'); |
||
63 | * $media->setType('audio/mpeg'); |
||
64 | * |
||
65 | * // add it to the item |
||
66 | * $item->addMedia($media); |
||
67 | * |
||
68 | * // add the item to the feed (almost there) |
||
69 | * $feed->add($item); |
||
70 | * |
||
71 | * // format it in atom |
||
72 | * $feedIo->toAtom($feed); |
||
73 | * </code> |
||
74 | * |
||
75 | */ |
||
76 | class FeedIo |
||
77 | { |
||
78 | |||
79 | /** |
||
80 | * @var \FeedIo\Reader |
||
81 | */ |
||
82 | protected $reader; |
||
83 | |||
84 | /** |
||
85 | * @var \FeedIo\Rule\DateTimeBuilder |
||
86 | */ |
||
87 | protected $dateTimeBuilder; |
||
88 | |||
89 | /** |
||
90 | * @var \FeedIo\Adapter\ClientInterface; |
||
91 | */ |
||
92 | protected $client; |
||
93 | |||
94 | /** |
||
95 | * @var \Psr\Log\LoggerInterface |
||
96 | */ |
||
97 | protected $logger; |
||
98 | |||
99 | /** |
||
100 | * @var array |
||
101 | */ |
||
102 | protected $standards; |
||
103 | |||
104 | /** |
||
105 | * @var \FeedIo\Reader\FixerSet |
||
106 | */ |
||
107 | protected $fixerSet; |
||
108 | |||
109 | /** |
||
110 | * @param \FeedIo\Adapter\ClientInterface $client |
||
111 | * @param \Psr\Log\LoggerInterface $logger |
||
112 | */ |
||
113 | 12 | public function __construct(ClientInterface $client, LoggerInterface $logger, DateTimeBuilderInterface $dateTimeBuilder = null) |
|
114 | { |
||
115 | 12 | $this->client = $client; |
|
116 | 12 | $this->logger = $logger; |
|
117 | 12 | $this->dateTimeBuilder = $dateTimeBuilder ?? new DateTimeBuilder($logger); |
|
0 ignored issues
–
show
|
|||
118 | 12 | $this->setReader(new Reader($client, $logger)); |
|
119 | 12 | $this->loadCommonStandards(); |
|
120 | 12 | $this->loadFixerSet(); |
|
121 | 12 | } |
|
122 | |||
123 | /** |
||
124 | * Loads main standards (RSS, RDF, Atom) in current object's attributes |
||
125 | * |
||
126 | * @return FeedIo |
||
127 | */ |
||
128 | 12 | protected function loadCommonStandards() : FeedIo |
|
129 | { |
||
130 | 12 | $standards = $this->getCommonStandards(); |
|
131 | 12 | foreach ($standards as $name => $standard) { |
|
132 | 12 | $this->addStandard($name, $standard); |
|
133 | } |
||
134 | |||
135 | 12 | return $this; |
|
136 | } |
||
137 | |||
138 | /** |
||
139 | * adds a filter to the reader |
||
140 | * |
||
141 | * @param \FeedIo\FilterInterface $filter |
||
142 | * @return FeedIo |
||
143 | */ |
||
144 | 2 | public function addFilter(FilterInterface $filter) : FeedIo |
|
145 | { |
||
146 | 2 | $this->getReader()->addFilter($filter); |
|
147 | |||
148 | 2 | return $this; |
|
149 | } |
||
150 | |||
151 | /** |
||
152 | * Returns main standards |
||
153 | * |
||
154 | * @return array |
||
155 | */ |
||
156 | 12 | public function getCommonStandards() : array |
|
157 | { |
||
158 | 12 | $loader = new Loader(); |
|
159 | |||
160 | 12 | return $loader->getCommonStandards($this->getDateTimeBuilder()); |
|
161 | } |
||
162 | |||
163 | /** |
||
164 | * @param string $name |
||
165 | * @param \FeedIo\StandardAbstract $standard |
||
166 | * @return FeedIo |
||
167 | */ |
||
168 | 12 | public function addStandard(string $name, StandardAbstract $standard) : FeedIo |
|
169 | { |
||
170 | 12 | $name = strtolower($name); |
|
171 | 12 | $this->standards[$name] = $standard; |
|
172 | 12 | $parser = $this->newParser($standard->getSyntaxFormat(), $standard); |
|
173 | 12 | $this->reader->addParser($parser); |
|
174 | |||
175 | 12 | return $this; |
|
176 | } |
||
177 | |||
178 | /** |
||
179 | * @param string $format |
||
180 | * @param StandardAbstract $standard |
||
181 | * @return ParserAbstract |
||
182 | */ |
||
183 | 11 | public function newParser(string $format, StandardAbstract $standard) : ParserAbstract |
|
184 | { |
||
185 | 11 | $reflection = new \ReflectionClass("FeedIo\\Parser\\{$format}Parser"); |
|
186 | |||
187 | 11 | if (! $reflection->isSubclassOf('FeedIo\ParserAbstract')) { |
|
188 | throw new \InvalidArgumentException(); |
||
189 | } |
||
190 | |||
191 | 11 | return $reflection->newInstanceArgs([$standard, $this->logger]); |
|
192 | } |
||
193 | |||
194 | /** |
||
195 | * @return \FeedIo\Reader\FixerSet |
||
196 | */ |
||
197 | 1 | public function getFixerSet() : FixerSet |
|
198 | { |
||
199 | 1 | return $this->fixerSet; |
|
200 | } |
||
201 | |||
202 | /** |
||
203 | * @return FeedIo |
||
204 | */ |
||
205 | 11 | protected function loadFixerSet() : FeedIo |
|
206 | { |
||
207 | 11 | $this->fixerSet = new FixerSet(); |
|
208 | 11 | $fixers = $this->getBaseFixers(); |
|
209 | |||
210 | 11 | foreach ($fixers as $fixer) { |
|
211 | 11 | $this->addFixer($fixer); |
|
212 | } |
||
213 | |||
214 | 11 | return $this; |
|
215 | } |
||
216 | |||
217 | /** |
||
218 | * @param FixerAbstract $fixer |
||
219 | * @return FeedIo |
||
220 | */ |
||
221 | 11 | public function addFixer(FixerAbstract $fixer) : FeedIo |
|
222 | { |
||
223 | 11 | $fixer->setLogger($this->logger); |
|
224 | 11 | $this->fixerSet->add($fixer); |
|
225 | |||
226 | 11 | return $this; |
|
227 | } |
||
228 | |||
229 | /** |
||
230 | * @return array |
||
231 | */ |
||
232 | 11 | public function getBaseFixers() : array |
|
233 | { |
||
234 | return array( |
||
235 | 11 | new Reader\Fixer\HttpLastModified(), |
|
236 | 11 | new Reader\Fixer\PublicId(), |
|
237 | 11 | ); |
|
238 | 11 | } |
|
239 | |||
240 | /** |
||
241 | * @param array $formats |
||
242 | * @return FeedIo |
||
243 | */ |
||
244 | public function addDateFormats(array $formats) : FeedIo |
||
245 | { |
||
246 | foreach ($formats as $format) { |
||
247 | $this->getDateTimeBuilder()->addDateFormat($format); |
||
248 | } |
||
249 | |||
250 | return $this; |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * @return \FeedIo\Rule\DateTimeBuilder |
||
255 | */ |
||
256 | public function getDateTimeBuilder() : DateTimeBuilder |
||
257 | { |
||
258 | 12 | return $this->dateTimeBuilder; |
|
259 | } |
||
260 | 12 | ||
261 | /** |
||
262 | * @return \FeedIo\Reader |
||
263 | */ |
||
264 | public function getReader() : Reader |
||
265 | { |
||
266 | 4 | return $this->reader; |
|
267 | } |
||
268 | 4 | ||
269 | /** |
||
270 | * @param \FeedIo\Reader $reader |
||
271 | * @return FeedIo |
||
272 | */ |
||
273 | public function setReader(Reader $reader) : FeedIo |
||
274 | { |
||
275 | 12 | $this->reader = $reader; |
|
276 | |||
277 | 12 | return $this; |
|
278 | } |
||
279 | 12 | ||
280 | /** |
||
281 | * Discover feeds from the webpage's headers |
||
282 | * @param string $url |
||
283 | * @return array |
||
284 | */ |
||
285 | public function discover(string $url) : array |
||
286 | { |
||
287 | 1 | $explorer = new Explorer($this->client, $this->logger); |
|
288 | |||
289 | 1 | return $explorer->discover($url); |
|
290 | } |
||
291 | 1 | ||
292 | /** |
||
293 | * @param iterable $requests |
||
294 | * @param CallbackInterface $callback |
||
295 | * @param string $feedClass |
||
296 | */ |
||
297 | public function readAsync(iterable $requests, CallbackInterface $callback, string $feedClass = '\FeedIo\Feed') : void |
||
298 | { |
||
299 | $reader = new AsyncReader($this->reader, $this->reader->getClient(), $callback, $feedClass); |
||
0 ignored issues
–
show
$this->reader->getClient() of type object<FeedIo\Adapter\ClientInterface> is not a sub-type of object<FeedIo\Adapter\Guzzle\Client> . It seems like you assume a concrete implementation of the interface FeedIo\Adapter\ClientInterface to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
300 | |||
301 | $reader->process($requests); |
||
302 | } |
||
303 | |||
304 | /** |
||
305 | * @param string $url |
||
306 | * @param FeedInterface $feed |
||
307 | * @param \DateTime $modifiedSince |
||
308 | * @return \FeedIo\Reader\Result |
||
309 | */ |
||
310 | public function read(string $url, FeedInterface $feed = null, \DateTime $modifiedSince = null) : Result |
||
311 | { |
||
312 | 2 | if (is_null($feed)) { |
|
313 | $feed = new Feed(); |
||
314 | 2 | } |
|
315 | 1 | ||
316 | if ($modifiedSince instanceof \DateTime) { |
||
317 | $this->addFilter(new ModifiedSince($modifiedSince)); |
||
318 | 2 | } |
|
319 | 1 | ||
320 | $this->logAction($feed, "read access : $url into a feed instance"); |
||
321 | $result = $this->reader->read($url, $feed, $modifiedSince); |
||
322 | 2 | ||
323 | 2 | $this->fixerSet->correct($result); |
|
324 | $this->resetFilters(); |
||
325 | 2 | ||
326 | 2 | return $result; |
|
327 | } |
||
328 | 2 | ||
329 | /** |
||
330 | * @param string $url |
||
331 | * @param \DateTime $modifiedSince |
||
332 | * @return \FeedIo\Reader\Result |
||
333 | */ |
||
334 | public function readSince(string $url, \DateTime $modifiedSince) : Result |
||
335 | { |
||
336 | 1 | return $this->read($url, new Feed(), $modifiedSince); |
|
337 | } |
||
338 | 1 | ||
339 | /** |
||
340 | * @return FeedIo |
||
341 | */ |
||
342 | public function resetFilters() : FeedIo |
||
343 | { |
||
344 | 2 | $this->getReader()->resetFilters(); |
|
345 | |||
346 | 2 | return $this; |
|
347 | } |
||
348 | 2 | ||
349 | /** |
||
350 | * Get a PSR-7 compliant response for the given feed |
||
351 | * |
||
352 | * @param \FeedIo\FeedInterface $feed |
||
353 | * @param string $standard |
||
354 | * @param int $maxAge |
||
355 | * @param bool $public |
||
356 | * @return ResponseInterface |
||
357 | */ |
||
358 | public function getPsrResponse(FeedInterface $feed, string $standard, int $maxAge = 600, bool $public = true) : ResponseInterface |
||
359 | { |
||
360 | 1 | $this->logAction($feed, "creating a PSR 7 Response in $standard format"); |
|
361 | |||
362 | 1 | $formatter = $this->getStandard($standard)->getFormatter(); |
|
363 | $responseBuilder = new ResponseBuilder($maxAge, $public); |
||
364 | 1 | ||
365 | 1 | return $responseBuilder->createResponse($standard, $formatter, $feed); |
|
366 | } |
||
367 | 1 | ||
368 | /** |
||
369 | * @param FeedInterface $feed |
||
370 | * @param string $standard Standard's name |
||
371 | * @return string |
||
372 | */ |
||
373 | public function format(FeedInterface $feed, string $standard) : string |
||
374 | { |
||
375 | 1 | $this->logAction($feed, "formatting a feed in $standard format"); |
|
376 | |||
377 | 1 | $formatter = $this->getStandard($standard)->getFormatter(); |
|
378 | |||
379 | 1 | return $formatter->toString($feed); |
|
380 | } |
||
381 | 1 | ||
382 | /** |
||
383 | * @param \FeedIo\FeedInterface $feed |
||
384 | * @return string |
||
385 | */ |
||
386 | public function toRss(FeedInterface $feed) : string |
||
387 | { |
||
388 | 1 | return $this->format($feed, 'rss'); |
|
389 | } |
||
390 | 1 | ||
391 | /** |
||
392 | * @param \FeedIo\FeedInterface $feed |
||
393 | * @return string |
||
394 | */ |
||
395 | public function toAtom(FeedInterface $feed) : string |
||
396 | { |
||
397 | 1 | return $this->format($feed, 'atom'); |
|
398 | } |
||
399 | 1 | ||
400 | /** |
||
401 | * @param \FeedIo\FeedInterface $feed |
||
402 | * @return string |
||
403 | */ |
||
404 | public function toJson(FeedInterface $feed) : string |
||
405 | { |
||
406 | 1 | return $this->format($feed, 'json'); |
|
407 | } |
||
408 | 1 | ||
409 | |||
410 | /** |
||
411 | * @param string $name |
||
412 | * @return \FeedIo\StandardAbstract |
||
413 | * @throws \OutOfBoundsException |
||
414 | */ |
||
415 | public function getStandard(string $name) : StandardAbstract |
||
416 | { |
||
417 | 3 | $name = strtolower($name); |
|
418 | if (array_key_exists($name, $this->standards)) { |
||
419 | 3 | return $this->standards[$name]; |
|
420 | 3 | } |
|
421 | 2 | ||
422 | throw new \OutOfBoundsException("no standard found for $name"); |
||
423 | } |
||
424 | 1 | ||
425 | /** |
||
426 | * @param \FeedIo\FeedInterface $feed |
||
427 | * @param string $message |
||
428 | * @return FeedIo |
||
429 | */ |
||
430 | protected function logAction(FeedInterface $feed, string $message) : FeedIo |
||
431 | { |
||
432 | 3 | $class = get_class($feed); |
|
433 | $this->logger->debug("$message (feed class : $class)"); |
||
434 | 3 | ||
435 | 3 | return $this; |
|
436 | } |
||
437 | } |
||
438 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.
Either this assignment is in error or an instanceof check should be added for that assignment.