Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
8 / 8
CRAP
100.00% covered (success)
100.00%
1 / 1
HasPageMetadata
100.00% covered (success)
100.00%
36 / 36
100.00% covered (success)
100.00%
8 / 8
23
100.00% covered (success)
100.00%
1 / 1
 getCanonicalUrl
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDynamicMetadata
100.00% covered (success)
100.00%
21 / 21
100.00% covered (success)
100.00%
1 / 1
10
 renderPageMetadata
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 canUseCanonicalUrl
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
2
 canUseSitemapLink
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 canUseRssFeedLink
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
6
 hasTwitterTitleInConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasOpenGraphTitleInConfig
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace Hyde\Framework\Concerns;
4
5use Hyde\Framework\Helpers\Meta;
6use Hyde\Framework\Hyde;
7use Hyde\Framework\Models\MarkdownPost;
8use Hyde\Framework\Services\RssFeedService;
9use Hyde\Framework\Services\SitemapService;
10
11/**
12 * @todo Move logic into service class to make it easier to test.
13 *
14 * @see \Tests\Feature\Concerns\HasPageMetadataTest
15 */
16trait HasPageMetadata
17{
18    public function getCanonicalUrl(): string
19    {
20        return Hyde::uriPath(Hyde::pageLink($this->getCurrentPagePath().'.html'));
21    }
22
23    public function getDynamicMetadata(): array
24    {
25        $array = [];
26
27        if ($this->canUseCanonicalUrl()) {
28            $array[] = '<link rel="canonical" href="'.$this->getCanonicalUrl().'" />';
29        }
30
31        if ($this->canUseSitemapLink()) {
32            $array[] = '<link rel="sitemap" type="application/xml" title="Sitemap" href="'.Hyde::uriPath('sitemap.xml').'" />';
33        }
34
35        if ($this->canUseRssFeedlink()) {
36            $array[] = '<link rel="alternate" type="application/rss+xml" title="'
37            .RssFeedService::getTitle()
38            .' RSS Feed" href="'
39            .Hyde::uriPath(RssFeedService::getDefaultOutputFilename())
40            .'" />';
41        }
42
43        if (isset($this->title)) {
44            if ($this->hasTwitterTitleInConfig()) {
45                $array[] = '<meta name="twitter:title" content="'.config('hyde.name', 'HydePHP').' - '.$this->title.'" />';
46            }
47            if ($this->hasOpenGraphTitleInConfig()) {
48                $array[] = '<meta property="og:title" content="'.config('hyde.name', 'HydePHP').' - '.$this->title.'" />';
49            }
50        }
51
52        if ($this instanceof MarkdownPost) {
53            // Temporarily merge data with GeneratesPageMetadata trait for compatibility
54            $array[] = "\n<!-- Blog Post Meta Tags -->";
55            foreach ($this->getMetadata() as $name => $content) {
56                $array[] = Meta::name($name, $content);
57            }
58            foreach ($this->getMetaProperties() as $property => $content) {
59                $array[] = Meta::property($property, $content);
60            }
61        }
62
63        return $array;
64    }
65
66    public function renderPageMetadata(): string
67    {
68        $dynamicMetadata = $this->getDynamicMetadata();
69
70        return Meta::render(
71            $dynamicMetadata
72        );
73    }
74
75    public function canUseCanonicalUrl(): bool
76    {
77        return Hyde::uriPath() && isset($this->slug);
78    }
79
80    public function canUseSitemapLink(): bool
81    {
82        return SitemapService::canGenerateSitemap();
83    }
84
85    public function canUseRssFeedLink(): bool
86    {
87        if (RssFeedService::canGenerateFeed() && isset($this->slug)) {
88            if ($this instanceof MarkdownPost) {
89                return true;
90            }
91
92            if (str_starts_with($this->getCurrentPagePath(), 'post')) {
93                return true;
94            }
95
96            if ($this->getCurrentPagePath() === 'index') {
97                return true;
98            }
99        }
100
101        return false;
102    }
103
104    public function hasTwitterTitleInConfig(): bool
105    {
106        return str_contains(json_encode(config('hyde.meta', [])), 'twitter:title');
107    }
108
109    public function hasOpenGraphTitleInConfig(): bool
110    {
111        return str_contains(json_encode(config('hyde.meta', [])), 'og:title');
112    }
113}