• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

eliashaeussler / cache-warmup / 17635578449

11 Sep 2025 06:05AM UTC coverage: 90.061%. Remained the same
17635578449

push

github

web-flow
[TASK] Update all dependencies (#544)

* [TASK] Update all dependencies

* [BUGFIX] Be more precise in catching possible datetime errors

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Elias Häußler <elias@haeussler.dev>

0 of 1 new or added line in 1 file covered. (0.0%)

1785 of 1982 relevant lines covered (90.06%)

10.18 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.75
/src/Xml/Node/SitemapNodeConverter.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of the Composer package "eliashaeussler/cache-warmup".
7
 *
8
 * Copyright (C) 2020-2025 Elias Häußler <elias@haeussler.dev>
9
 *
10
 * This program is free software: you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation, either version 3 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22
 */
23

24
namespace EliasHaeussler\CacheWarmup\Xml\Node;
25

26
use DateTimeImmutable;
27
use DateTimeInterface;
28
use EliasHaeussler\CacheWarmup\Exception;
29
use EliasHaeussler\CacheWarmup\Sitemap;
30
use GuzzleHttp\Psr7;
31
use Throwable;
32

33
/**
34
 * SitemapNodeConverter.
35
 *
36
 * @author Elias Häußler <elias@haeussler.dev>
37
 * @license GPL-3.0-or-later
38
 *
39
 * @internal
40
 */
41
final class SitemapNodeConverter
42
{
43
    private const DATE_FORMATS = [
44
        DateTimeInterface::W3C,
45
        'Y-m-d\TH:i:s.v\Z',
46
        '!Y-m-d',
47
    ];
48

49
    /**
50
     * @param array{loc?: string, lastmod?: string} $node
51
     *
52
     * @throws Exception\SitemapIsMalformed
53
     */
54
    public function convertSitemap(array $node, Sitemap\Sitemap $origin): Sitemap\Sitemap
8✔
55
    {
56
        if (!isset($node[SitemapNode::Location->value])) {
8✔
57
            throw new Exception\SitemapIsMalformed($origin);
1✔
58
        }
59

60
        $uri = new Psr7\Uri($node[SitemapNode::Location->value]);
7✔
61
        $lastModificationDate = null;
7✔
62

63
        if (isset($node[SitemapNode::LastModificationDate->value])) {
7✔
64
            $lastModificationDate = $this->parseLastModificationDate($node[SitemapNode::LastModificationDate->value]);
6✔
65
        }
66

67
        try {
68
            return new Sitemap\Sitemap($uri, $lastModificationDate, $origin);
7✔
69
        } catch (Exception\LocalFilePathIsMissingInUrl|Exception\UrlIsEmpty|Exception\UrlIsInvalid $exception) {
1✔
70
            throw new Exception\SitemapIsMalformed($origin, previous: $exception);
1✔
71
        }
72
    }
73

74
    /**
75
     * @param array{loc?: string, priority?: string, lastmod?: string, changefreq?: string} $node
76
     *
77
     * @throws Exception\SitemapIsMalformed
78
     */
79
    public function convertUrl(array $node, Sitemap\Sitemap $origin): Sitemap\Url
8✔
80
    {
81
        if (!isset($node[SitemapNode::Location->value])) {
8✔
82
            throw new Exception\SitemapIsMalformed($origin);
1✔
83
        }
84

85
        $uri = $node[SitemapNode::Location->value];
7✔
86
        $priority = (float) ($node[SitemapNode::Priority->value] ?? 0.5);
7✔
87
        $lastModificationDate = null;
7✔
88
        $changeFrequency = null;
7✔
89

90
        if (isset($node[SitemapNode::LastModificationDate->value])) {
7✔
91
            $lastModificationDate = $this->parseLastModificationDate($node[SitemapNode::LastModificationDate->value]);
6✔
92
        }
93
        if (isset($node[SitemapNode::ChangeFrequency->value])) {
7✔
94
            $changeFrequency = Sitemap\ChangeFrequency::fromCaseInsensitive($node[SitemapNode::ChangeFrequency->value]);
1✔
95
        }
96

97
        try {
98
            return new Sitemap\Url($uri, $priority, $lastModificationDate, $changeFrequency, $origin);
7✔
99
        } catch (Exception\UrlIsEmpty|Exception\UrlIsInvalid $exception) {
1✔
100
            throw new Exception\SitemapIsMalformed($origin, previous: $exception);
1✔
101
        }
102
    }
103

104
    private function parseLastModificationDate(string $datetime): ?DateTimeImmutable
12✔
105
    {
106
        foreach (self::DATE_FORMATS as $dateFormat) {
12✔
107
            try {
108
                $lastModificationDate = DateTimeImmutable::createFromFormat($dateFormat, $datetime);
12✔
NEW
109
            } catch (Throwable) {
×
110
                // Try next format
111
                continue;
×
112
            }
113

114
            if (false !== $lastModificationDate) {
12✔
115
                return $lastModificationDate;
8✔
116
            }
117
        }
118

119
        return null;
4✔
120
    }
121
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc