Completed
Push — develop ( e90b1b...7d8e41 )
by Baptiste
01:58
created

Atom   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 105
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 7
dl 0
loc 105
ccs 72
cts 72
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A key() 0 3 1
B parse() 0 85 5
A __construct() 0 6 1
1
<?php
2
declare(strict_types = 1);
3
4
namespace PersonalGalaxy\RSS\Parser;
5
6
use PersonalGalaxy\RSS\Entity\{
7
    Article,
8
    Article\Author,
9
    Article\Description,
10
    Article\Title,
11
};
12
use Innmind\Url\Url;
13
use Innmind\Crawler\{
14
    Parser,
15
    HttpResource\Attribute\Attribute,
16
};
17
use Innmind\Http\Message\{
18
    Request,
19
    Response,
20
};
21
use Innmind\Xml\{
22
    ReaderInterface,
23
    NodeInterface,
24
    ElementInterface,
25
};
26
use Innmind\TimeContinuum\TimeContinuumInterface;
27
use Innmind\Immutable\{
28
    MapInterface,
29
    SetInterface,
30
    Set,
31
    StreamInterface,
32
    Stream,
33
};
34
35
final class Atom implements Parser
36
{
37
    private $reader;
38
    private $clock;
39
40 4
    public function __construct(
41
        ReaderInterface $reader,
42
        TimeContinuumInterface $clock
43
    ) {
44 4
        $this->reader = $reader;
45 4
        $this->clock = $clock;
46 4
    }
47
48 3
    public function parse(
49
        Request $request,
50
        Response $response,
51
        MapInterface $attributes
52
    ): MapInterface {
53
        if (
54 3
            !$response->headers()->has('content-type') ||
55 3
            (string) $response->headers()->get('content-type')->values()->current() !== 'application/atom'
56
        ) {
57 2
            return $attributes;
58
        }
59
60 1
        $xml = $this->reader->read($response->body());
61
        $articles = $xml
62 1
            ->children()
63 1
            ->values()
64 1
            ->first() // feed node
65 1
            ->children()
66 1
            ->values()
67 1
            ->filter(static function(NodeInterface $node): bool {
68 1
                return $node instanceof ElementInterface && $node->name() === 'entry';
69 1
            })
70 1
            ->reduce(
71 1
                Set::of(Article::class),
72 1
                function(SetInterface $articles, ElementInterface $item): SetInterface {
73
                    $elements = $item
74 1
                        ->children()
75 1
                        ->values()
76 1
                        ->filter(static function(NodeInterface $node): bool {
77 1
                            return $node instanceof ElementInterface;
78 1
                        });
79
                    $link = $elements
80 1
                        ->filter(static function(ElementInterface $element): bool {
81 1
                            return $element->name() === 'link';
82 1
                        })
83 1
                        ->first()
84 1
                        ->attributes()
85 1
                        ->get('href')
86 1
                        ->value();
87
                    $author = $elements
88 1
                        ->filter(static function(ElementInterface $element): bool {
89 1
                            return $element->name() === 'author';
90 1
                        })
91 1
                        ->first()
92 1
                        ->children()
93 1
                        ->values()
94 1
                        ->filter(static function(NodeInterface $node): bool {
95 1
                            return $node instanceof ElementInterface && $node->name() === 'name';
96 1
                        })
97 1
                        ->first()
98 1
                        ->content();
99
                    $description = $elements
100 1
                        ->filter(static function(ElementInterface $element): bool {
101 1
                            return $element->name() === 'content';
102 1
                        })
103 1
                        ->first()
104 1
                        ->content();
105
                    $title = $elements
106 1
                        ->filter(static function(ElementInterface $element): bool {
107 1
                            return $element->name() === 'title';
108 1
                        })
109 1
                        ->first()
110 1
                        ->content();
111
                    $publicationDate = $elements
112 1
                        ->filter(static function(ElementInterface $element): bool {
113 1
                            return $element->name() === 'updated';
114 1
                        })
115 1
                        ->first()
116 1
                        ->content();
117
118 1
                    return $articles->add(Article::fetch(
119 1
                        Url::fromString(trim($link)),
120 1
                        new Author(trim($author)),
121 1
                        new Description(trim($description)),
122 1
                        new Title(trim($title)),
123 1
                        $this->clock->at(trim($publicationDate))
124
                    ));
125 1
                }
126
            );
127
128 1
        return $attributes->put(
129 1
            self::key(),
130 1
            new Attribute(
131 1
                self::key(),
132 1
                $articles
133
            )
134
        );
135
    }
136
137 2
    public static function key(): string
138
    {
139 2
        return 'articles';
140
    }
141
}
142