Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
6 / 6
CRAP
100.00% covered (success)
100.00%
1 / 1
GeneratesPageMetadata
100.00% covered (success)
100.00%
28 / 28
100.00% covered (success)
100.00%
6 / 6
19
100.00% covered (success)
100.00%
1 / 1
 constructMetadata
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 getMetadata
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMetaProperties
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 parseFrontMatterMetadata
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 makeOpenGraphPropertiesForArticle
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
8
 getAuthorName
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace Hyde\Framework\Concerns;
4
5use Hyde\Framework\Hyde;
6use Hyde\Framework\Models\MarkdownPost;
7use Tests\TestCase;
8
9/**
10 * Generates metadata for page models that have front matter.
11 *
12 * @see \Hyde\Framework\Models\Metadata
13 * @see \Tests\Feature\Concerns\GeneratesPageMetadataTest
14 */
15trait GeneratesPageMetadata
16{
17    public array $metadata = [];
18    public array $properties = [];
19
20    public function constructMetadata(): void
21    {
22        $this->parseFrontMatterMetadata();
23
24        if ($this instanceof MarkdownPost || $this instanceof TestCase) {
25            $this->makeOpenGraphPropertiesForArticle();
26        }
27    }
28
29    public function getMetadata(): array
30    {
31        return $this->metadata;
32    }
33
34    public function getMetaProperties(): array
35    {
36        return $this->properties;
37    }
38
39    /**
40     * Generate metadata from the front matter that can be used in standard <meta> tags.
41     * This helper is page type agnostic and works with any kind of model having front matter.
42     */
43    protected function parseFrontMatterMetadata(): void
44    {
45        if (isset($this->matter['description'])) {
46            $this->metadata['description'] = $this->matter['description'];
47        }
48
49        if (isset($this->matter['author'])) {
50            $this->metadata['author'] = $this->getAuthorName($this->matter['author']);
51        }
52
53        if (isset($this->matter['category'])) {
54            $this->metadata['keywords'] = $this->matter['category'];
55        }
56    }
57
58    /**
59     * Generate opengraph metadata from front matter for an og:article such as a blog post.
60     */
61    protected function makeOpenGraphPropertiesForArticle(): void
62    {
63        $this->properties['og:type'] = 'article';
64        if (Hyde::uriPath()) {
65            $this->properties['og:url'] = Hyde::uriPath(Hyde::pageLink('posts/'.$this->slug.'.html'));
66        }
67
68        if (isset($this->matter['title'])) {
69            $this->properties['og:title'] = $this->matter['title'];
70        }
71
72        if (isset($this->matter['date'])) {
73            $this->properties['og:article:published_time'] = date('c', strtotime($this->matter['date']));
74        }
75
76        if (isset($this->matter['image'])) {
77            if (is_string($this->matter['image'])) {
78                $this->properties['og:image'] = $this->matter['image'];
79            } else {
80                if (isset($this->matter['image']['path'])) {
81                    $this->properties['og:image'] = $this->matter['image']['path'];
82                }
83                if (isset($this->matter['image']['uri'])) {
84                    $this->properties['og:image'] = $this->matter['image']['uri'];
85                }
86            }
87        }
88    }
89
90    /**
91     * Parse the author name string from front matter with support for both flat and array notation.
92     *
93     * @param  string|array  $author
94     * @return string
95     */
96    protected function getAuthorName(string|array $author): string
97    {
98        if (is_string($author)) {
99            return $author;
100        }
101
102        return $author['name'] ?? $author['username'] ?? 'Guest';
103    }
104}