Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
Sitemap
100.00% covered (success)
100.00%
38 / 38
100.00% covered (success)
100.00%
3 / 3
11
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 getEntry
100.00% covered (success)
100.00%
32 / 32
100.00% covered (success)
100.00%
1 / 1
8
 getExtraNamespaces
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3/**
4 * Class for representing sitemap files
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Villanova University 2010.
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 version 2,
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 * @category VuFind
24 * @package  Sitemap
25 * @author   Demian Katz <demian.katz@villanova.edu>
26 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org Main Page
28 */
29
30namespace VuFind\Sitemap;
31
32use function is_array;
33
34/**
35 * Class for representing sitemap files
36 *
37 * @category VuFind
38 * @package  Sitemap
39 * @author   Demian Katz <demian.katz@villanova.edu>
40 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
41 * @link     https://vufind.org Main Page
42 */
43class Sitemap extends AbstractFile
44{
45    public const XHTML_NAMESPACE = 'xmlns:xhtml="http://www.w3.org/1999/xhtml"';
46
47    /**
48     * Frequency of URL updates (always, daily, weekly, monthly, yearly, never)
49     *
50     * @var string
51     */
52    protected $frequency;
53
54    /**
55     * Alternative languages
56     *
57     * @var array
58     */
59    protected $alternativeLanguages = [];
60
61    /**
62     * Whether the XHTML namespace is needed
63     *
64     * @var bool
65     */
66    protected $xhtmlNamespaceNeeded = false;
67
68    /**
69     * Constructor
70     *
71     * @param string $frequency Frequency of URL updates
72     */
73    public function __construct($frequency = 'weekly')
74    {
75        $this->topTag = 'urlset';
76        $this->frequency = $frequency;
77    }
78
79    /**
80     * Translate a URL into an appropriate entry for this sitemap file.
81     *
82     * @param string|array $url URL as a string or as an associative array
83     *
84     * @return string XML fragment
85     */
86    protected function getEntry($url)
87    {
88        if (is_array($url)) {
89            $link = $url['url'];
90            $languages = $url['languages'] ?? [];
91            $frequency = $url['frequency'] ?? '';
92            $lastmod = $url['lastmod'] ?? '';
93        } else {
94            $link = $url;
95            $languages = [];
96            $frequency = '';
97            $lastmod = '';
98        }
99        $alternativeLinks = '';
100        if ($languages) {
101            $lngParam = !str_contains($link, '?') ? '?lng=' : '&lng=';
102            $links = [];
103            foreach ($languages as $sitemapLng => $vufindLng) {
104                $lngLink = $vufindLng
105                    ? $link . $lngParam . urlencode($vufindLng) : $link;
106                $links[] = '<xhtml:link rel="alternate" hreflang="'
107                    . htmlspecialchars($sitemapLng) . '">'
108                    . htmlspecialchars($lngLink)
109                    . '</xhtml:link>';
110            }
111
112            $alternativeLinks = '  ' . implode("\n  ", $links) . "\n";
113            $this->xhtmlNamespaceNeeded = true;
114        } else {
115            $locs[] = '<loc>' . htmlspecialchars($link) . '</loc>';
116        }
117        $link = htmlspecialchars($link);
118        $freq = htmlspecialchars($frequency ?: $this->frequency);
119        $lastmod = htmlspecialchars($lastmod);
120        return "<url>\n"
121            . "  <loc>$link</loc>\n"
122            . "  <changefreq>$freq</changefreq>\n"
123            . ($lastmod ? "  <lastmod>$lastmod</lastmod>\n" : '')
124            . $alternativeLinks
125            . "</url>\n";
126    }
127
128    /**
129     * Get any extra namespace declarations needed for the sitemap
130     *
131     * @return array
132     */
133    protected function getExtraNamespaces()
134    {
135        $result = parent::getExtraNamespaces();
136        if ($this->xhtmlNamespaceNeeded) {
137            $result[] = Sitemap::XHTML_NAMESPACE;
138        }
139        return $result;
140    }
141}