Passed
Push — master ( cd665a...cab8f4 )
by Caen
03:04 queued 11s
created

MetadataBag::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Hyde\Framework\Models\Metadata;
4
5
use Hyde\Framework\Concerns\HydePage;
6
use Hyde\Framework\Contracts\MetadataItemContract;
7
use Hyde\Framework\Helpers\Meta;
8
use Hyde\Framework\Hyde;
9
use Hyde\Framework\Models\Pages\MarkdownPost;
10
11
/**
12
 * @see \Hyde\Framework\Testing\Feature\MetadataTest
13
 */
14
class MetadataBag
15
{
16
    protected HydePage $page;
17
18
    public array $links = [];
19
    public array $metadata = [];
20
    public array $properties = [];
21
    public array $generics = [];
22
23
    public function __construct(?HydePage $page = null)
24
    {
25
        if ($page) {
26
            $this->page = $page;
27
            $this->generate();
28
        }
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
        $this->addDynamicPageMetadata($this->page);
64
    }
65
66
    protected function addDynamicPageMetadata(HydePage $page): void
67
    {
68
        if ($page->has('canonicalUrl')) {
69
            $this->add(Meta::link('canonical', $page->get('canonicalUrl')));
70
        }
71
72
        if ($page->has('title')) {
73
            $this->add(Meta::name('twitter:title', $page->htmlTitle()));
74
            $this->add(Meta::property('title', $page->htmlTitle()));
75
        }
76
77
        if ($page instanceof MarkdownPost) {
78
            $this->addMetadataForMarkdownPost($page);
79
        }
80
    }
81
82
    protected function addMetadataForMarkdownPost(MarkdownPost $page): void
83
    {
84
        $this->addPostMetadataIfExists($page, 'description');
85
        $this->addPostMetadataIfExists($page, 'author');
86
        $this->addPostMetadataIfExists($page, 'category', 'keywords');
87
        $this->addPostMetadataIfExists($page, 'canonicalUrl', 'url');
88
89
        if ($page->has('canonicalUrl')) {
90
            $this->add(Meta::property('url', $page->get('canonicalUrl')));
91
        }
92
93
        if ($page->has('date')) {
94
            $this->add(Meta::property('og:article:published_time', $page->date->datetime));
95
        }
96
97
        if ($page->has('image')) {
98
            $this->add(Meta::property('image', $this->resolveImageLink($page->get('image'))));
99
        }
100
101
        $this->add(Meta::property('type', 'article'));
102
    }
103
104
    protected function addPostMetadataIfExists(MarkdownPost $page, string $property, ?string $name = null): void
105
    {
106
        if ($page->has($property)) {
107
            $this->add(Meta::name($name ?? $property, $page->get($property)));
108
        }
109
    }
110
111
    protected function getPrefixedArray(string $group): array
112
    {
113
        $array = [];
114
        foreach ($this->{$group} as $key => $value) {
115
            $array[$group.':'.$key] = $value;
116
        }
117
118
        return $array;
119
    }
120
121
    protected function resolveImageLink(string $image): string
122
    {
123
        // Since this is run before the page is rendered, we don't have the currentPage property
124
        // but since we know that this is for a blog post we know what the property will be
125
        // since Hyde does not currently support custom Blog post output directories.
126
        return str_starts_with($image, 'http') ? $image : "../$image";
127
    }
128
}
129