Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
41 / 41 |
|
100.00% |
8 / 8 |
CRAP | |
100.00% |
1 / 1 |
SitemapService | |
100.00% |
41 / 41 |
|
100.00% |
8 / 8 |
21 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
generate | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
5 | |||
getXML | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
addPageModelUrls | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
3 | |||
getLastModDate | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getPriority | |
100.00% |
12 / 12 |
|
100.00% |
1 / 1 |
6 | |||
generateSitemap | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
canGenerateSitemap | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | namespace Hyde\Framework\Services; |
4 | |
5 | use Hyde\Framework\Helpers\Features; |
6 | use Hyde\Framework\Hyde; |
7 | use Hyde\Framework\Models\BladePage; |
8 | use Hyde\Framework\Models\DocumentationPage; |
9 | use Hyde\Framework\Models\MarkdownPage; |
10 | use Hyde\Framework\Models\MarkdownPost; |
11 | use SimpleXMLElement; |
12 | |
13 | /** |
14 | * @see \Tests\Feature\Services\SitemapServiceTest |
15 | * @see https://www.sitemaps.org/protocol.html |
16 | */ |
17 | class SitemapService |
18 | { |
19 | public SimpleXMLElement $xmlElement; |
20 | protected float $time_start; |
21 | |
22 | public function __construct() |
23 | { |
24 | $this->time_start = microtime(true); |
25 | |
26 | $this->xmlElement = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9"></urlset>'); |
27 | $this->xmlElement->addAttribute('generator', 'HydePHP '.Hyde::version()); |
28 | } |
29 | |
30 | public function generate(): self |
31 | { |
32 | if (Features::hasBladePages()) { |
33 | $this->addPageModelUrls( |
34 | BladePage::class |
35 | ); |
36 | } |
37 | |
38 | if (Features::hasMarkdownPages()) { |
39 | $this->addPageModelUrls( |
40 | MarkdownPage::class |
41 | ); |
42 | } |
43 | |
44 | if (Features::hasBlogPosts()) { |
45 | $this->addPageModelUrls( |
46 | MarkdownPost::class, |
47 | 'posts/' |
48 | ); |
49 | } |
50 | |
51 | if (Features::hasDocumentationPages()) { |
52 | $this->addPageModelUrls( |
53 | DocumentationPage::class, |
54 | Hyde::docsDirectory().'/' |
55 | ); |
56 | } |
57 | |
58 | return $this; |
59 | } |
60 | |
61 | public function getXML(): string |
62 | { |
63 | $this->xmlElement->addAttribute('processing_time_ms', (string) round((microtime(true) - $this->time_start) * 1000, 2)); |
64 | |
65 | return $this->xmlElement->asXML(); |
66 | } |
67 | |
68 | public function addPageModelUrls(string $pageClass, string $routePrefix = ''): void |
69 | { |
70 | $collection = CollectionService::getSourceFileListForModel($pageClass); |
71 | |
72 | foreach ($collection as $slug) { |
73 | $urlItem = $this->xmlElement->addChild('url'); |
74 | $urlItem->addChild('loc', htmlentities(Hyde::uriPath(Hyde::pageLink($routePrefix.$slug.'.html')))); |
75 | $urlItem->addChild('lastmod', htmlentities($this->getLastModDate($pageClass, $slug))); |
76 | $urlItem->addChild('changefreq', 'daily'); |
77 | if (config('hyde.sitemap.dynamic_priority', true)) { |
78 | $urlItem->addChild('priority', $this->getPriority($pageClass, $slug)); |
79 | } |
80 | } |
81 | } |
82 | |
83 | protected function getLastModDate(string $pageClass, string $slug): string |
84 | { |
85 | return date('c', filemtime( |
86 | /** @var \Hyde\Framework\Contracts\AbstractPage $pageClass */ |
87 | Hyde::path($pageClass::$sourceDirectory.DIRECTORY_SEPARATOR.$slug.$pageClass::$fileExtension) |
88 | )); |
89 | } |
90 | |
91 | protected function getPriority(string $pageClass, string $slug): string |
92 | { |
93 | $priority = 0.5; |
94 | |
95 | if (in_array($pageClass, [BladePage::class, MarkdownPage::class])) { |
96 | $priority = 0.9; |
97 | if ($slug === 'index') { |
98 | $priority = 1; |
99 | } |
100 | if ($slug === '404') { |
101 | $priority = 0.5; |
102 | } |
103 | } |
104 | |
105 | if ($pageClass === DocumentationPage::class) { |
106 | $priority = 0.9; |
107 | } |
108 | |
109 | if ($pageClass === MarkdownPost::class) { |
110 | $priority = 0.75; |
111 | } |
112 | |
113 | return (string) $priority; |
114 | } |
115 | |
116 | public static function generateSitemap(): string |
117 | { |
118 | return (new static)->generate()->getXML(); |
119 | } |
120 | |
121 | public static function canGenerateSitemap(): bool |
122 | { |
123 | return (Hyde::uriPath() !== false) |
124 | && config('hyde.generate_sitemap', true) |
125 | && extension_loaded('simplexml'); |
126 | } |
127 | } |