Test Failed
Push — master ( fa45c0...33acf1 )
by compolom
01:21
created

RssReader   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 90
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 48
dl 0
loc 90
rs 10
c 1
b 0
f 0
wmc 13

5 Methods

Rating   Name   Duplication   Size   Complexity  
A addChannel() 0 7 2
A getAll() 0 36 5
A getCacheIds() 0 6 2
A getCacheChannels() 0 6 2
A __construct() 0 17 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Compolomus\RssReader;
6
7
use DateTime;
8
use DOMDocument;
9
use DOMXPath;
10
use SplFileObject;
11
use Symfony\Component\Dotenv\Dotenv;
12
13
use function PHPUnit\Framework\fileExists;
14
15
class RssReader
16
{
17
    private SplFileObject $cache;
18
19
    private SplFileObject $cacheIds;
20
21
    private string $cacheFile;
22
23
    private string $cacheIdsFile;
24
25
    public function __construct(string $envFile = __DIR__ . '/.env')
26
    {
27
        $dotenv = new Dotenv();
28
        $dotenv->load($envFile);
29
        $dir = $_ENV['CACHEDIR'];
30
31
        $this->cacheFile = $dir . '/cacheChannels.txt';
32
        $this->cacheIdsFile = $dir . '/cacheIds.txt';
33
34
35
        if (!is_dir($dir)) {
36
            mkdir($dir);
37
        }
38
39
40
        $this->cache = new SplFileObject($this->cacheFile, 'a+b');
41
        $this->cacheIds = new SplFileObject($this->cacheIdsFile, 'a+b');
42
    }
43
44
    public function addChannel(string $url): bool
45
    {
46
        if (!in_array($url, file($this->cacheFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES), true)) {
47
            return (bool) $this->cache->fwrite($url . PHP_EOL);
48
        }
49
50
        return false;
51
    }
52
53
    public function getAll(): array
54
    {
55
        $dom = new DOMDocument();
56
        $result = [];
57
        $ids = [];
58
59
        foreach ($this->getCacheChannels() as $chanel) {
60
            $dom->load($chanel);
61
            $items = $dom->getElementsByTagName('item');
62
            $xpath = new DOMXpath($dom);
63
            foreach ($items as $item) {
64
                $link = $item->getElementsByTagName('link')->item(0)->nodeValue;
65
                preg_match('#\/(\d{3,})\/{0,1}#', $link, $matches);
66
                $timestamp = (new DateTime($item->getElementsByTagName('pubDate')->item(0)->nodeValue))->getTimestamp();
67
                $id = $matches[1];
68
                $cacheId = $id . '-' . $timestamp;
69
                if (!in_array($cacheId, $this->getCacheIds(), true)) {
70
                    $result[] = [
71
                        'id' => $id,
72
                        'title' => $item->getElementsByTagName('title')->item(0)->nodeValue,
73
                        'desc' => trim(strip_tags($item->getElementsByTagName('description')->item(0)->nodeValue)),
74
                        'link' => $link,
75
                        'timestamp' => $timestamp,
76
                        'img' => $xpath->query('//enclosure/@url')->item(0)->nodeValue,
77
                        'cacheId' => $cacheId
78
                    ];
79
                    $ids[] = $cacheId;
80
                }
81
            }
82
        }
83
84
        if (count($ids)) {
85
            $this->cacheIds->fwrite(implode(PHP_EOL, $ids) . PHP_EOL);
86
        }
87
88
        return $result;
89
    }
90
91
    protected function getCacheChannels(): array
92
    {
93
        return fileExists($this->cacheFile) ? file(
94
            $this->cacheFile,
95
            FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
96
        ) : [];
97
    }
98
99
    protected function getCacheIds(): array
100
    {
101
        return fileExists($this->cacheIdsFile) ? file(
102
            $this->cacheIdsFile,
103
            FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES
104
        ) : [];
105
    }
106
107
}
108