Passed
Push — master ( 80ddec...cae974 )
by Caen
03:33 queued 12s
created

Metadata::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 7
rs 10
1
<?php
2
3
namespace Hyde\Framework\Models\Metadata;
4
5
use Hyde\Framework\Contracts\AbstractPage;
6
use Hyde\Framework\Contracts\MetadataItemContract;
7
use Hyde\Framework\Helpers\Features;
8
use Hyde\Framework\Helpers\Meta;
9
use Hyde\Framework\Hyde;
10
use Hyde\Framework\Models\Pages\MarkdownPost;
11
use Hyde\Framework\Services\RssFeedService;
12
13
/**
14
 * @see \Hyde\Framework\Testing\Feature\MetadataTest
15
 */
16
class Metadata
17
{
18
    protected AbstractPage $page;
19
20
    public array $links = [];
21
    public array $metadata = [];
22
    public array $properties = [];
23
    public array $generics = [];
24
25
    public function __construct(AbstractPage $page)
26
    {
27
        $this->page = $page;
28
        $this->generate();
29
    }
30
31
    public function render(): string
32
    {
33
        return implode("\n", $this->get());
34
    }
35
36
    public function get(): array
37
    {
38
        return array_merge(
39
            $this->getPrefixedArray('links'),
40
            $this->getPrefixedArray('metadata'),
41
            $this->getPrefixedArray('properties'),
42
            $this->getPrefixedArray('generics')
43
        );
44
    }
45
46
    public function add(MetadataItemContract|string $item): static
47
    {
48
        if ($item instanceof LinkItem) {
49
            $this->links[$item->uniqueKey()] = $item;
50
        } elseif ($item instanceof MetadataItem) {
51
            $this->metadata[$item->uniqueKey()] = $item;
52
        } elseif ($item instanceof OpenGraphItem) {
53
            $this->properties[$item->uniqueKey()] = $item;
54
        } else {
55
            $this->generics[] = $item;
56
        }
57
58
        return $this;
59
    }
60
61
    protected function generate(): void
62
    {
63
        foreach (config('hyde.meta', []) as $item) {
64
            $this->add($item);
65
        }
66
67
        if (Features::sitemap()) {
68
            $this->add(Meta::link('sitemap', Hyde::url('sitemap.xml'), [
69
                'type' => 'application/xml', 'title' => 'Sitemap',
70
            ]));
71
        }
72
73
        if (Features::rss()) {
74
            $this->add(Meta::link('alternate', Hyde::url(RssFeedService::getDefaultOutputFilename()), [
75
                'type' => 'application/rss+xml', 'title' => RssFeedService::getDescription(),
76
            ]));
77
        }
78
79
        if ($this->page->has('canonicalUrl')) {
80
            $this->add(Meta::link('canonical', $this->page->canonicalUrl));
0 ignored issues
show
Bug introduced by
It seems like $this->page->canonicalUrl can also be of type null; however, parameter $href of Hyde\Framework\Helpers\Meta::link() 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

80
            $this->add(Meta::link('canonical', /** @scrutinizer ignore-type */ $this->page->canonicalUrl));
Loading history...
81
        }
82
83
        if ($this->page->has('title')) {
84
            $this->add(Meta::name('twitter:title', $this->page->htmlTitle()));
85
            $this->add(Meta::property('title', $this->page->htmlTitle()));
86
        }
87
88
        if ($this->page instanceof MarkdownPost) {
89
            $this->addMetadataForMarkdownPost($this->page);
90
        }
91
    }
92
93
    protected function addMetadataForMarkdownPost(MarkdownPost $page): void
94
    {
95
        if ($page->has('description')) {
96
            $this->add(Meta::name('description', $page->get('description')));
97
        }
98
99
        if ($page->has('author')) {
100
            $this->add(Meta::name('author', $page->get('author')));
101
        }
102
103
        if ($page->has('category')) {
104
            $this->add(Meta::name('keywords', $page->get('category')));
105
        }
106
107
        if ($page->has('canonicalUrl')) {
108
            $this->add(Meta::property('url', $page->get('canonicalUrl')));
109
        }
110
111
        if ($page->has('title')) {
112
            $this->add(Meta::property('title', $page->get('title')));
113
        }
114
115
        if ($page->has('date')) {
116
            $this->add(Meta::property('og:article:published_time', $page->date->datetime));
117
        }
118
119
        if ($page->has('image')) {
120
            $this->add(Meta::property('image', $this->resolveImageLink($page->get('image'))));
121
        }
122
123
        $this->add(Meta::property('type', 'article'));
124
    }
125
126
    protected function getPrefixedArray(string $group): array
127
    {
128
        $array = [];
129
        foreach ($this->{$group} as $key => $value) {
130
            $array[$group.':'.$key] = $value;
131
        }
132
133
        return $array;
134
    }
135
136
    protected function resolveImageLink(string $image): string
137
    {
138
        // Since this is run before the page is rendered, we don't have the currentPage property
139
        // but since we know that this is for a blog post we know what the property will be
140
        // since Hyde does not currently support custom Blog post output directories.
141
        return str_starts_with($image, 'http') ? $image : "../$image";
142
    }
143
}
144