Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
91.89% covered (success)
91.89%
34 / 37
60.00% covered (warning)
60.00%
3 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
ContentPages
91.89% covered (success)
91.89%
34 / 37
60.00% covered (warning)
60.00%
3 / 5
15.12
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 setOptions
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getSitemapName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getUrls
100.00% covered (success)
100.00%
27 / 27
100.00% covered (success)
100.00%
1 / 1
9
 isExcluded
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3/**
4 * Content pages generator plugin
5 *
6 * PHP version 8
7 *
8 * Copyright (C) The National Library of Finland 2021.
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   Ere Maijala <ere.maijala@helsinki.fi>
26 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
27 * @link     https://vufind.org/wiki/development:plugins:ils_drivers Wiki
28 */
29
30namespace VuFind\Sitemap\Plugin;
31
32use Laminas\Config\Config;
33use Laminas\Router\RouteStackInterface;
34use VuFindTheme\ThemeInfo;
35use Webmozart\Glob\Glob;
36
37use function in_array;
38use function strlen;
39
40/**
41 * Content pages generator plugin
42 *
43 * @category VuFind
44 * @package  Sitemap
45 * @author   Ere Maijala <ere.maijala@helsinki.fi>
46 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
47 * @link     https://vufind.org/wiki/development:plugins:ils_drivers Wiki
48 */
49class ContentPages extends AbstractGeneratorPlugin
50{
51    /**
52     * Theme informations
53     *
54     * @var ThemeInfo
55     */
56    protected $themeInfo;
57
58    /**
59     * Router
60     *
61     * @var RouteStackInterface
62     */
63    protected $router;
64
65    /**
66     * Base URL for site
67     *
68     * @var string
69     */
70    protected $baseUrl;
71
72    /**
73     * Main VuFind configuration (config.ini)
74     *
75     * @var Config
76     */
77    protected $config;
78
79    /**
80     * Patterns of files to be included
81     *
82     * @see https://github.com/webmozarts/glob
83     *
84     * @var array
85     */
86    protected $includedFiles = [
87        [
88            'path' => 'templates/content/',
89            'pattern' => '**/*.phtml',
90        ],
91        [
92            'path' => 'templates/content/',
93            'pattern' => '**/*.md',
94        ],
95    ];
96
97    /**
98     * Patterns of files to be ignored when searching for content pages
99     *
100     * @see https://github.com/webmozarts/glob
101     *
102     * @var array
103     */
104    protected $excludedFiles = [
105        'templates/content/content.phtml', // Content main page
106        'templates/content/markdown.phtml', // Content main page for Markdown
107    ];
108
109    /**
110     * Constructor
111     *
112     * @param ThemeInfo           $themeInfo Theme info
113     * @param RouteStackInterface $router    Router
114     * @param Config              $config    Main VuFind configuration
115     */
116    public function __construct(
117        ThemeInfo $themeInfo,
118        RouteStackInterface $router,
119        Config $config
120    ) {
121        $this->themeInfo = $themeInfo;
122        $this->router = $router;
123        $this->config = $config;
124    }
125
126    /**
127     * Set plugin options.
128     *
129     * @param array $options Options
130     *
131     * @return void
132     */
133    public function setOptions(array $options): void
134    {
135        parent::setOptions($options);
136        $this->baseUrl = $options['baseUrl'] ?? '';
137    }
138
139    /**
140     * Get the name of the sitemap used to create the sitemap file. This will be
141     * appended to the configured base name, and may be blank to use the base
142     * name without a suffix.
143     *
144     * @return string
145     */
146    public function getSitemapName(): string
147    {
148        return 'pages';
149    }
150
151    /**
152     * Generate urls for the sitemap.
153     *
154     * @return \Generator
155     */
156    public function getUrls(): \Generator
157    {
158        $nonLanguageFiles = [];
159        $languages = isset($this->config->Languages)
160            ? array_keys($this->config->Languages->toArray())
161            : [];
162        foreach ($this->includedFiles as $fileSpec) {
163            $files = $this->themeInfo->findInThemes([$fileSpec['path'] . $fileSpec['pattern']]);
164            // Check each file for language suffix and combine the files into a
165            // non-language specific array
166            $pathLen = strlen($fileSpec['path']);
167            foreach ($files as $fileInfo) {
168                if ($this->isExcluded($fileInfo['relativeFile'])) {
169                    continue;
170                }
171                // Get file name relative to the original path
172                $pathInfo = pathinfo($fileInfo['relativeFile']);
173                if ($pagePath = substr($pathInfo['dirname'], $pathLen)) {
174                    $pagePath .= '/';
175                }
176                $pageName = $pagePath . $pathInfo['filename'];
177                // Check the filename for a known language suffix
178                $p = strrpos($pageName, '_');
179                if ($p > 0) {
180                    $fileLanguage = substr($pageName, $p + 1);
181                    if (in_array($fileLanguage, $languages)) {
182                        $pageName = substr($pageName, 0, $p);
183                    }
184                }
185                $nonLanguageFiles[$pageName] = true;
186            }
187        }
188
189        foreach (array_keys($nonLanguageFiles) as $fileName) {
190            $url = $this->baseUrl . $this->router->assemble(
191                ['page' => $fileName],
192                ['name' => 'content-page']
193            );
194            $this->verboseMsg("Adding content page $url");
195            yield $url;
196        }
197    }
198
199    /**
200     * Check if the given file should be excluded from sitemap
201     *
202     * @param string $filename Filename
203     *
204     * @return bool
205     */
206    protected function isExcluded(string $filename): bool
207    {
208        foreach ($this->excludedFiles as $pattern) {
209            if (Glob::match($filename, $pattern)) {
210                return true;
211            }
212        }
213        return false;
214    }
215}