Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 36 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
HeadScript | |
0.00% |
0 / 36 |
|
0.00% |
0 / 10 |
462 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
getFileType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
itemToString | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
30 | |||
forcePrependFile | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
30 | |||
isExcludedFromConcat | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
getResourceFilePath | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setResourceFilePath | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getMinifier | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMinifiedData | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
addNonce | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * Head script view helper (extended for VuFind's theme system) |
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 View_Helpers |
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/wiki/development Wiki |
28 | */ |
29 | |
30 | namespace VuFindTheme\View\Helper; |
31 | |
32 | use VuFindTheme\ThemeInfo; |
33 | |
34 | use function array_key_exists; |
35 | |
36 | /** |
37 | * Head script view helper (extended for VuFind's theme system) |
38 | * |
39 | * @category VuFind |
40 | * @package View_Helpers |
41 | * @author Demian Katz <demian.katz@villanova.edu> |
42 | * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License |
43 | * @link https://vufind.org/wiki/development Wiki |
44 | * |
45 | * @method getWhitespace(string|int $indent) |
46 | * @method getIndent() |
47 | * @method getSeparator() |
48 | */ |
49 | class HeadScript extends \Laminas\View\Helper\HeadScript implements \Laminas\Log\LoggerAwareInterface |
50 | { |
51 | use ConcatTrait { |
52 | getMinifiedData as getBaseMinifiedData; |
53 | } |
54 | use RelativePathTrait; |
55 | use \VuFind\Log\LoggerAwareTrait; |
56 | |
57 | /** |
58 | * Theme information service |
59 | * |
60 | * @var ThemeInfo |
61 | */ |
62 | protected $themeInfo; |
63 | |
64 | /** |
65 | * CSP nonce |
66 | * |
67 | * @var string |
68 | */ |
69 | protected $cspNonce; |
70 | |
71 | /** |
72 | * Constructor |
73 | * |
74 | * @param ThemeInfo $themeInfo Theme information service |
75 | * @param string|bool $plconfig Config for current application environment |
76 | * @param string $nonce Nonce from nonce generator |
77 | */ |
78 | public function __construct(ThemeInfo $themeInfo, $plconfig = false, $nonce = '') |
79 | { |
80 | parent::__construct(); |
81 | $this->themeInfo = $themeInfo; |
82 | $this->usePipeline = $this->enabledInConfig($plconfig); |
83 | $this->cspNonce = $nonce; |
84 | $this->optionalAttributes[] = 'nonce'; |
85 | } |
86 | |
87 | /** |
88 | * Folder name and file extension for trait |
89 | * |
90 | * @return string |
91 | */ |
92 | protected function getFileType() |
93 | { |
94 | return 'js'; |
95 | } |
96 | |
97 | /** |
98 | * Create script HTML |
99 | * |
100 | * @param mixed $item Item to convert |
101 | * @param string $indent String to add before the item |
102 | * @param string $escapeStart Starting sequence |
103 | * @param string $escapeEnd Ending sequence |
104 | * |
105 | * @return string |
106 | */ |
107 | public function itemToString($item, $indent, $escapeStart, $escapeEnd) |
108 | { |
109 | // Normalize href to account for themes (if appropriate): |
110 | if (!empty($item->attributes['src']) && $this->isRelativePath($item->attributes['src'])) { |
111 | $relPath = 'js/' . $item->attributes['src']; |
112 | $details = $this->themeInfo |
113 | ->findContainingTheme($relPath, ThemeInfo::RETURN_ALL_DETAILS); |
114 | |
115 | if (!empty($details)) { |
116 | $urlHelper = $this->getView()->plugin('url'); |
117 | $url = $urlHelper('home') . "themes/{$details['theme']}/" . $relPath; |
118 | $url .= strstr($url, '?') ? '&_=' : '?_='; |
119 | $url .= filemtime($details['path']); |
120 | $item->attributes['src'] = $url; |
121 | } |
122 | } |
123 | |
124 | $this->addNonce($item); |
125 | return parent::itemToString($item, $indent, $escapeStart, $escapeEnd); |
126 | } |
127 | |
128 | /** |
129 | * Forcibly prepend a file removing it from any existing position |
130 | * |
131 | * @param string $src Script src |
132 | * @param string $type Script type |
133 | * @param array $attrs Array of script attributes |
134 | * |
135 | * @return void |
136 | */ |
137 | public function forcePrependFile( |
138 | $src = null, |
139 | $type = 'text/javascript', |
140 | array $attrs = [] |
141 | ) { |
142 | // Look for existing entry and remove it if found. Comparison method |
143 | // copied from isDuplicate(). |
144 | foreach ($this->getContainer() as $offset => $item) { |
145 | if ( |
146 | ($item->source === null) |
147 | && array_key_exists('src', $item->attributes) |
148 | && ($src === $item->attributes['src']) |
149 | ) { |
150 | $this->offsetUnset($offset); |
151 | break; |
152 | } |
153 | } |
154 | parent::prependFile($src, $type, $attrs); |
155 | } |
156 | |
157 | /** |
158 | * Returns true if file should not be included in the compressed concat file |
159 | * Required by ConcatTrait |
160 | * |
161 | * @param stdClass $item Script element object |
162 | * |
163 | * @return bool |
164 | */ |
165 | protected function isExcludedFromConcat($item) |
166 | { |
167 | return empty($item->attributes['src']) |
168 | || isset($item->attributes['conditional']) |
169 | || !$this->isRelativePath($item->attributes['src']); |
170 | } |
171 | |
172 | /** |
173 | * Get the file path from the script object |
174 | * Required by ConcatTrait |
175 | * |
176 | * @param stdClass $item Script element object |
177 | * |
178 | * @return string |
179 | */ |
180 | protected function getResourceFilePath($item) |
181 | { |
182 | return $item->attributes['src']; |
183 | } |
184 | |
185 | /** |
186 | * Set the file path of the script object |
187 | * Required by ConcatTrait |
188 | * |
189 | * @param stdClass $item Script element object |
190 | * @param string $path New path string |
191 | * |
192 | * @return stdClass |
193 | */ |
194 | protected function setResourceFilePath($item, $path) |
195 | { |
196 | $item->attributes['src'] = $path; |
197 | return $item; |
198 | } |
199 | |
200 | /** |
201 | * Get the minifier that can handle these file types |
202 | * Required by ConcatTrait |
203 | * |
204 | * @return \MatthiasMullie\Minify\JS |
205 | */ |
206 | protected function getMinifier() |
207 | { |
208 | return new \MatthiasMullie\Minify\JS(); |
209 | } |
210 | |
211 | /** |
212 | * Get minified data for a file |
213 | * |
214 | * @param array $details File details |
215 | * @param string $concatPath Target path for the resulting file (used in minifier |
216 | * for path mapping) |
217 | * |
218 | * @throws \Exception |
219 | * @return string |
220 | */ |
221 | protected function getMinifiedData($details, $concatPath) |
222 | { |
223 | $data = $this->getBaseMinifiedData($details, $concatPath); |
224 | // Play it safe by terminating a script with a semicolon |
225 | if (!str_ends_with(trim($data), ';')) { |
226 | $data .= ';'; |
227 | } |
228 | return $data; |
229 | } |
230 | |
231 | /** |
232 | * Add a nonce to the item |
233 | * |
234 | * @param stdClass $item Item |
235 | * |
236 | * @return void |
237 | */ |
238 | protected function addNonce($item) |
239 | { |
240 | $item->attributes['nonce'] = $this->cspNonce; |
241 | } |
242 | } |