RssFeedGenerator   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 109
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 44
dl 0
loc 109
rs 10
c 0
b 0
f 0
wmc 16

11 Methods

Rating   Name   Duplication   Size   Complexity  
A generate() 0 7 1
A getDescription() 0 3 1
A getImageType() 0 3 1
A getImageLength() 0 3 1
A addBaseChannelItems() 0 10 1
A getFilename() 0 3 1
A addItem() 0 8 1
A getChannel() 0 5 1
A constructBaseElement() 0 11 1
A addDynamicItemData() 0 25 6
A addAtomLinkItem() 0 7 1
1
<?php
2
3
/** @noinspection PhpComposerExtensionStubsInspection */
4
/** @noinspection XmlUnusedNamespaceDeclaration */
5
6
declare(strict_types=1);
7
8
namespace Hyde\Framework\Features\XmlGenerators;
9
10
use Hyde\Hyde;
11
use SimpleXMLElement;
12
use Hyde\Facades\Site;
13
use Hyde\Facades\Config;
14
use Hyde\Pages\MarkdownPost;
15
use Hyde\Facades\Filesystem;
16
use Hyde\Framework\Features\Blogging\Models\FeaturedImage;
17
18
use function date;
19
use function assert;
20
use function sprintf;
21
use function implode;
22
23
/**
24
 * @see https://validator.w3.org/feed/docs/rss2.html
25
 */
26
class RssFeedGenerator extends BaseXmlGenerator
27
{
28
    public function generate(): static
29
    {
30
        MarkdownPost::getLatestPosts()->each(function (MarkdownPost $post): void {
31
            $this->addItem($post);
32
        });
33
34
        return $this;
35
    }
36
37
    protected function constructBaseElement(): void
38
    {
39
        $this->xmlElement = new SimpleXMLElement(implode("\n", [
40
            '<?xml version="1.0" encoding="UTF-8"?>',
41
            '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" />',
42
        ]));
43
44
        $this->xmlElement->addChild('channel');
45
46
        $this->addBaseChannelItems();
47
        $this->addAtomLinkItem();
48
    }
49
50
    protected function addItem(MarkdownPost $post): void
51
    {
52
        $item = $this->getChannel()->addChild('item');
53
54
        $this->addChild($item, 'title', $post->title);
55
        $this->addChild($item, 'description', $post->description);
0 ignored issues
show
Bug introduced by
It seems like $post->description can also be of type null; however, parameter $value of Hyde\Framework\Features\...mlGenerator::addChild() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

55
        $this->addChild($item, 'description', /** @scrutinizer ignore-type */ $post->description);
Loading history...
56
57
        $this->addDynamicItemData($item, $post);
58
    }
59
60
    protected function addDynamicItemData(SimpleXMLElement $item, MarkdownPost $post): void
61
    {
62
        if ($post->getCanonicalUrl() !== null) {
63
            $this->addChild($item, 'link', $post->getCanonicalUrl());
64
            $this->addChild($item, 'guid', $post->getCanonicalUrl());
65
        }
66
67
        if (isset($post->date)) {
68
            $this->addChild($item, 'pubDate', $post->date->format(DATE_RSS));
0 ignored issues
show
Bug introduced by
The method format() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
            $this->addChild($item, 'pubDate', $post->date->/** @scrutinizer ignore-call */ format(DATE_RSS));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method format() does not exist on Hyde\Support\Models\DateString. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
            $this->addChild($item, 'pubDate', $post->date->/** @scrutinizer ignore-call */ format(DATE_RSS));
Loading history...
69
        }
70
71
        if (isset($post->author)) {
72
            $item->addChild('dc:creator', $post->author->name, 'http://purl.org/dc/elements/1.1/');
73
        }
74
75
        if (isset($post->category)) {
76
            $this->addChild($item, 'category', $post->category);
0 ignored issues
show
Bug introduced by
It seems like $post->category can also be of type null; however, parameter $value of Hyde\Framework\Features\...mlGenerator::addChild() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

76
            $this->addChild($item, 'category', /** @scrutinizer ignore-type */ $post->category);
Loading history...
77
        }
78
79
        if (isset($post->image)) {
80
            $image = $item->addChild('enclosure');
81
82
            $image->addAttribute('url', Hyde::url($post->image->getSource()));
0 ignored issues
show
Bug introduced by
The method getSource() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

82
            $image->addAttribute('url', Hyde::url($post->image->/** @scrutinizer ignore-call */ getSource()));

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Bug introduced by
The method url() does not exist on Hyde\Hyde. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

82
            $image->addAttribute('url', Hyde::/** @scrutinizer ignore-call */ url($post->image->getSource()));
Loading history...
83
            $image->addAttribute('type', $this->getImageType($post->image));
0 ignored issues
show
Bug introduced by
It seems like $post->image can also be of type null; however, parameter $image of Hyde\Framework\Features\...nerator::getImageType() does only seem to accept Hyde\Framework\Features\...ng\Models\FeaturedImage, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

83
            $image->addAttribute('type', $this->getImageType(/** @scrutinizer ignore-type */ $post->image));
Loading history...
84
            $image->addAttribute('length', $this->getImageLength($post->image));
0 ignored issues
show
Bug introduced by
It seems like $post->image can also be of type null; however, parameter $image of Hyde\Framework\Features\...rator::getImageLength() does only seem to accept Hyde\Framework\Features\...ng\Models\FeaturedImage, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

84
            $image->addAttribute('length', $this->getImageLength(/** @scrutinizer ignore-type */ $post->image));
Loading history...
85
        }
86
    }
87
88
    protected function addBaseChannelItems(): void
89
    {
90
        $channel = $this->getChannel();
91
92
        $this->addChild($channel, 'title', Site::name());
0 ignored issues
show
Bug introduced by
It seems like Hyde\Facades\Site::name() can also be of type null; however, parameter $value of Hyde\Framework\Features\...mlGenerator::addChild() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

92
        $this->addChild($channel, 'title', /** @scrutinizer ignore-type */ Site::name());
Loading history...
93
        $this->addChild($channel, 'link', Site::url());
94
        $this->addChild($channel, 'description', $this->getDescription());
95
        $this->addChild($channel, 'language', Config::getString('hyde.language', 'en'));
96
        $this->addChild($channel, 'generator', 'HydePHP '.Hyde::version());
97
        $this->addChild($channel, 'lastBuildDate', date(DATE_RSS));
98
    }
99
100
    protected function addAtomLinkItem(): void
101
    {
102
        $atomLink = $this->getChannel()->addChild('atom:link', namespace: 'http://www.w3.org/2005/Atom');
103
104
        $atomLink->addAttribute('href', $this->escape(Hyde::url($this->getFilename())));
105
        $atomLink->addAttribute('rel', 'self');
106
        $atomLink->addAttribute('type', 'application/rss+xml');
107
    }
108
109
    protected function getImageType(FeaturedImage $image): string
110
    {
111
        return Filesystem::findMimeType($image->getSource());
112
    }
113
114
    /** @return numeric-string */
0 ignored issues
show
Documentation Bug introduced by
The doc comment numeric-string at position 0 could not be parsed: Unknown type name 'numeric-string' at position 0 in numeric-string.
Loading history...
115
    protected function getImageLength(FeaturedImage $image): string
116
    {
117
        return (string) $image->getContentLength();
118
    }
119
120
    public static function getFilename(): string
121
    {
122
        return Config::getString('hyde.rss.filename', 'feed.xml');
123
    }
124
125
    public static function getDescription(): string
126
    {
127
        return Config::getString('hyde.rss.description', sprintf('%s RSS Feed', Site::name()));
128
    }
129
130
    protected function getChannel(): SimpleXMLElement
131
    {
132
        assert($this->xmlElement->channel instanceof SimpleXMLElement);
133
134
        return $this->xmlElement->channel;
135
    }
136
}
137