Passed
Push — master ( d1fdf5...82265f )
by Caen
04:18 queued 22s
created

SitemapGenerator::getLastModDate()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/** @noinspection PhpComposerExtensionStubsInspection */
4
5
declare(strict_types=1);
6
7
namespace Hyde\Framework\Features\XmlGenerators;
8
9
use Hyde\Hyde;
10
use SimpleXMLElement;
11
use Hyde\Facades\Config;
12
use Hyde\Pages\BladePage;
13
use Hyde\Pages\MarkdownPage;
14
use Hyde\Pages\MarkdownPost;
15
use Hyde\Support\Models\Route;
16
use Hyde\Pages\DocumentationPage;
17
use Hyde\Foundation\Facades\Routes;
18
use Hyde\Framework\Concerns\TracksExecutionTime;
19
20
use function blank;
21
use function filemtime;
22
use function in_array;
23
use function date;
24
use function time;
25
use function str_starts_with;
26
27
/**
28
 * @see https://www.sitemaps.org/protocol.html
29
 */
30
class SitemapGenerator extends BaseXmlGenerator
31
{
32
    use TracksExecutionTime;
33
34
    public function generate(): static
35
    {
36
        Routes::all()->each(function (Route $route): void {
37
            $this->addRoute($route);
38
        });
39
40
        return $this;
41
    }
42
43
    public function getXml(): string
44
    {
45
        $this->xmlElement->addAttribute('processing_time_ms', $this->getFormattedProcessingTime());
46
47
        return parent::getXml();
48
    }
49
50
    protected function constructBaseElement(): void
51
    {
52
        $this->startClock();
53
54
        $this->xmlElement = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
55
        $this->xmlElement->addAttribute('generator', 'HydePHP '.Hyde::version());
56
    }
57
58
    protected function addRoute(Route $route): void
59
    {
60
        $urlItem = $this->xmlElement->addChild('url');
61
62
        $this->addChild($urlItem, 'loc', $this->resolveRouteLink($route));
63
        $this->addChild($urlItem, 'lastmod', $this->getLastModDate($route->getSourcePath()));
64
        $this->addChild($urlItem, 'changefreq', 'daily');
65
66
        if (Config::getBool('hyde.sitemap.dynamic_priority', true)) {
67
            $this->addChild($urlItem, 'priority', $this->getPriority(
68
                $route->getPageClass(), $route->getPage()->getIdentifier()
69
            ));
70
        }
71
    }
72
73
    protected function getLastModDate(string $file): string
74
    {
75
        return date('c', @filemtime($file) ?: time());
76
    }
77
78
    protected function getPriority(string $pageClass, string $slug): string
79
    {
80
        $priority = 0.5;
81
82
        if (in_array($pageClass, [BladePage::class, MarkdownPage::class])) {
83
            $priority = 0.9;
84
            if ($slug === 'index') {
85
                $priority = 1;
86
            }
87
            if ($slug === '404') {
88
                $priority = 0.5;
89
            }
90
        }
91
92
        if ($pageClass === DocumentationPage::class) {
93
            $priority = 0.9;
94
        }
95
96
        if ($pageClass === MarkdownPost::class) {
97
            $priority = 0.75;
98
        }
99
100
        return (string) $priority;
101
    }
102
103
    /** @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...
104
    protected function getFormattedProcessingTime(): string
105
    {
106
        return (string) $this->getExecutionTimeInMs();
107
    }
108
109
    protected function resolveRouteLink(Route $route): string
110
    {
111
        $baseUrl = Config::getNullableString('hyde.url');
112
113
        if (blank($baseUrl) || str_starts_with($baseUrl, 'http://localhost')) {
0 ignored issues
show
Bug introduced by
It seems like $baseUrl can also be of type null; however, parameter $haystack of str_starts_with() 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

113
        if (blank($baseUrl) || str_starts_with(/** @scrutinizer ignore-type */ $baseUrl, 'http://localhost')) {
Loading history...
114
            // While the sitemap spec requires a full URL, we rather fall back
115
            // to using relative links instead of using localhost links.
116
117
            return $route->getLink();
118
        } else {
119
            return Hyde::url($route->getOutputPath());
120
        }
121
    }
122
}
123