Atom::key()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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