Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
ContentController
0.00% covered (danger)
0.00%
0 / 27
0.00% covered (danger)
0.00%
0 / 3
156
0.00% covered (danger)
0.00%
0 / 1
 contentAction
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
56
 getViewForMd
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 getViewForPhtml
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3/**
4 * Content Controller
5 *
6 * PHP version 8
7 *
8 * Copyright (C) Villanova University 2011.
9 * Copyright (C) The National Library of Finland 2014-2024.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2,
13 * as published by the Free Software Foundation.
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, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 *
24 * @category VuFind
25 * @package  Controller
26 * @author   Demian Katz <demian.katz@villanova.edu>
27 * @author   Ere Maijala <ere.maijala@helsinki.fi>
28 * @license  http://opensource.org/licenses/gpl-2.0.php GNU General Public License
29 * @link     https://vufind.org Main Page
30 */
31
32namespace VuFind\Controller;
33
34use Laminas\View\Model\ViewModel;
35
36use function is_callable;
37
38/**
39 * Controller for mostly static pages that doesn't fall under any particular
40 * function.
41 *
42 * @category VuFind
43 * @package  Controller
44 * @author   Demian Katz <demian.katz@villanova.edu>
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 Main Page
48 */
49class ContentController extends AbstractBase
50{
51    /**
52     * Types/formats of content
53     *
54     * @var array $types
55     */
56    protected $types = [
57        'phtml',
58        'md',
59    ];
60
61    /**
62     * Default action if none provided
63     *
64     * @return ViewModel
65     */
66    public function contentAction()
67    {
68        $pathPrefix = 'templates/content/';
69        $page = $this->params()->fromRoute('page');
70        // Path regex should prevent dots, but double-check to make sure:
71        if (str_contains($page, '..')) {
72            return $this->notFoundAction();
73        }
74        // Find last slash and add preceding part to path if found:
75        if (false !== ($p = strrpos($page, '/'))) {
76            $subPath = substr($page, 0, $p + 1);
77            $pathPrefix .= $subPath;
78            // Ensure the the path prefix does not contain extra slashes:
79            if (str_ends_with($pathPrefix, '//')) {
80                return $this->notFoundAction();
81            }
82            $page = substr($page, $p + 1);
83        }
84        $pageLocator = $this->serviceLocator->get(\VuFind\Content\PageLocator::class);
85        $data = $pageLocator->determineTemplateAndRenderer($pathPrefix, $page);
86
87        $method = isset($data) ? 'getViewFor' . ucwords($data['renderer']) : false;
88
89        return $method && is_callable([$this, $method])
90            ? $this->$method($data['page'], $data['relativePath'], $data['path'])
91            : $this->notFoundAction();
92    }
93
94    /**
95     * Get ViewModel for markdown based page
96     *
97     * @param string $page    Page name/route (if applicable)
98     * @param string $relPath Relative path to file with content (if applicable)
99     * @param string $path    Full path to file with content (if applicable)
100     *
101     * @return ViewModel
102     */
103    protected function getViewForMd(string $page, string $relPath, string $path): ViewModel
104    {
105        $view = $this->createViewModel(['data' => file_get_contents($path)]);
106        $view->setTemplate('content/markdown');
107        return $view;
108    }
109
110    /**
111     * Get ViewModel for phtml base page
112     *
113     * @param string $page    Page name/route (if applicable)
114     * @param string $relPath Relative path to file with content (if applicable)
115     * @param string $path    Full path to file with content (if applicable)
116     *
117     * @return ViewModel
118     */
119    protected function getViewForPhtml(string $page, string $relPath, string $path): ViewModel
120    {
121        // Convert relative path to a relative page name:
122        $relPage = $relPath;
123        if (str_starts_with($relPage, 'content/')) {
124            $relPage = substr($relPage, 8);
125        }
126        if (str_ends_with($relPage, '.phtml')) {
127            $relPage = substr($relPage, 0, -6);
128        }
129        // Prevent circular inclusion:
130        if ('content' === $relPage) {
131            return $this->notFoundAction();
132        }
133        return $this->createViewModel(['page' => $relPage]);
134    }
135}