Passed
Push — master ( 7a2a88...9a9b8c )
by Maurizio
14:27
created

NativeRenderer::sitemapTemplate()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 11
c 1
b 0
f 1
dl 0
loc 19
rs 9.9
cc 4
nc 8
nop 0
1
<?php
2
3
namespace Mfonte\Sitemap\Renderer;
4
5
use \DateTime;
0 ignored issues
show
Bug introduced by
The type \DateTime was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
6
7
use Mfonte\Sitemap\Tags\Sitemap;
8
use Mfonte\Sitemap\Tags\Url;
9
10
class NativeRenderer
11
{
12
    /**
13
     * Params Array. Should be injected into current instance with a compact() call, for example: compact('tags', 'hasImages', 'hasNews')
14
     *
15
     * @var array
16
     */
17
    private array $params;
18
19
    public static function instance(array $params) : self
20
    {
21
        return new self($params);
22
    }
23
24
    public function __construct(array $params)
25
    {
26
        $this->params = $params;
27
    }
28
29
    /**
30
     * Renders the sitemap or sitemap index
31
     *
32
     * @param string $type - sitemap or sitemapIndex
33
     *
34
     * @return string
35
     */
36
    public function render(string $type) : string
37
    {
38
        try {
39
            switch($type) {
40
                case 'sitemap':
41
                    $xml = $this->sitemapTemplate();
42
43
                    break;
44
                case 'sitemapIndex':
45
                    $xml = $this->sitemapIndexTemplate();
46
47
                    break;
48
                default:
49
                    throw new \Exception('Invalid Render Type', 999);
50
            }
51
        } catch(\Exception $e) {
52
            if ($e->getCode() === 999) {
53
                throw new \Exception('The render type must be "sitemap" or "sitemapIndex"');
54
            }
55
56
            throw new \Exception('Error while rendering the xml: ' . $e->getMessage());
57
        }
58
        
59
        if (! class_exists('\DOMDocument')) {
60
            return $xml;
61
        }
62
63
        $dom = new \DOMDocument();
64
        $dom->preserveWhiteSpace = false;
65
        $dom->formatOutput = true;
66
        $dom->loadXML($xml, LIBXML_NONET | LIBXML_NOWARNING | LIBXML_PARSEHUGE | LIBXML_NOERROR);
67
        $out = $dom->saveXML($dom->documentElement);
68
69
        if ($out === false) {
70
            throw new \Exception('DOMDocument: Error while prettifying the xml');
71
        }
72
73
        return $out;
74
    }
75
76
    private function sitemapIndexTemplate() : string
77
    {
78
        $template = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
79
        $template .= '<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
80
81
        foreach ($this->params['tags'] as $tag) {
82
            /** @var Sitemap $tag */
83
            
84
            $template .= '<sitemap>';
85
            if (! empty($tag->url)) {
86
                $template .= '<loc>' . url($tag->url) . '</loc>';
87
            }
88
89
            if (! empty($tag->lastModificationDate)) {
90
                $template .= '<lastmod>' . $tag->lastModificationDate->format(DateTime::ATOM) . '</lastmod>';
91
            }
92
93
            $template .= '</sitemap>';
94
        }
95
96
        $template .= '</sitemapindex>';
97
98
        return $template;
99
    }
100
101
    private function sitemapTemplate() : string
102
    {
103
        $template = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
104
        $template .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml"';
105
        if ($this->params['hasImages']) {
106
            $template .= ' xmlns:image="http://www.google.com/schemas/sitemap-image/1.1"';
107
        }
108
        if ($this->params['hasNews']) {
109
            $template .= ' xmlns:news="http://www.google.com/schemas/sitemap-news/0.9"';
110
        }
111
        $template .= '>';
112
113
        foreach ($this->params['tags'] as $tag) {
114
            $template .= $this->urlTemplate($tag);
115
        }
116
117
        $template .= '</urlset>';
118
119
        return $template;
120
    }
121
122
    private function urlTemplate(Url $tag) : string
123
    {
124
        $template = '<url>';
125
        if (! empty($tag->url)) {
126
            $template .= '<loc>' . url($tag->url) . '</loc>';
127
        }
128
        if (count($tag->alternates)) {
129
            foreach ($tag->alternates as $alternate) {
130
                $template .= '<xhtml:link rel="alternate" hreflang="' . $alternate->locale . '" href="' . url($alternate->url) . '" />';
131
            }
132
        }
133
        if (! empty($tag->lastModificationDate)) {
134
            $template .= '<lastmod>' . $tag->lastModificationDate->format(DateTime::ATOM) . '</lastmod>';
135
        }
136
        if (! empty($tag->changeFrequency)) {
137
            $template .= '<changefreq>' . $tag->changeFrequency . '</changefreq>';
138
        }
139
        if (! empty($tag->priority)) {
140
            $template .= '<priority>' . number_format($tag->priority, 1) . '</priority>';
141
        }
142
        if (count($tag->images)) {
143
            foreach ($tag->images as $image) {
144
                if (! empty($image->url)) {
145
                    $template .= '<image:image>';
146
                    $template .= '<image:loc>' . url($image->url) . '</image:loc>';
147
                    if (! empty($image->caption)) {
148
                        $template .= '<image:caption>' . $image->caption . '</image:caption>';
149
                    }
150
                    if (! empty($image->geo_location)) {
151
                        $template .= '<image:geo_location>' . $image->geo_location . '</image:geo_location>';
152
                    }
153
                    if (! empty($image->title)) {
154
                        $template .= '<image:title>' . $image->title . '</image:title>';
155
                    }
156
                    if (! empty($image->license)) {
157
                        $template .= '<image:license>' . $image->license . '</image:license>';
158
                    }
159
                    $template .= '</image:image>';
160
                }
161
            }
162
        }
163
        if (count($tag->news)) {
164
            foreach ($tag->news as $new) {
165
                $template .= '<news:news>';
166
                if (! empty($new->publication_date)) {
167
                    $template .= '<news:publication_date>' . $new->publication_date->format('Y-m-d') . '</news:publication_date>';
168
                }
169
                if (! empty($new->title)) {
170
                    $template .= '<news:title>' . $new->title . '</news:title>';
171
                }
172
                if (! empty($new->name) || ! empty($new->language)) {
173
                    $template .= '<news:publication>';
174
                    if (! empty($new->name)) {
175
                        $template .= '<news:name>' . $new->name . '</news:name>';
176
                    }
177
178
                    if (! empty($new->language)) {
179
                        $template .= '<news:language>' . $new->language . '</news:language>';
180
                    }
181
                    $template .= '</news:publication>';
182
                }
183
                $template .= '</news:news>';
184
            }
185
        }
186
187
        $template .= '</url>';
188
189
        return $template;
190
    }
191
}
192