1 <?php
2 3 4 5 6 7 8
9
10 defined('JPATH_PLATFORM') or die;
11
12 use Joomla\Utilities\ArrayHelper;
13
14 15 16 17 18
19 class JDocumentRendererHtmlHead extends JDocumentRenderer
20 {
21 22 23 24 25 26 27 28 29 30 31
32 public function render($head, $params = array(), $content = null)
33 {
34 return $this->fetchHead($this->_doc);
35 }
36
37 38 39 40 41 42 43 44 45 46
47 public function fetchHead($document)
48 {
49
50 if (isset($document->_metaTags['name']['tags']))
51 {
52 $tagsHelper = new JHelperTags;
53 $document->_metaTags['name']['tags'] = implode(', ', $tagsHelper->getTagNames($document->_metaTags['name']['tags']));
54 }
55
56 if ($document->getScriptOptions())
57 {
58 JHtml::_('behavior.core');
59 }
60
61
62 $app = JFactory::getApplication();
63 $app->triggerEvent('onBeforeCompileHead');
64
65
66 $lnEnd = $document->_getLineEnd();
67 $tab = $document->_getTab();
68 $tagEnd = ' />';
69 $buffer = '';
70 $mediaVersion = $document->getMediaVersion();
71
72
73 if ($document->isHtml5())
74 {
75 $buffer .= $tab . '<meta charset="' . $document->getCharset() . '" />' . $lnEnd;
76 }
77
78
79 $base = $document->getBase();
80
81 if (!empty($base))
82 {
83 $buffer .= $tab . '<base href="' . $base . '" />' . $lnEnd;
84 }
85
86
87 foreach ($document->_metaTags as $type => $tag)
88 {
89 foreach ($tag as $name => $content)
90 {
91 if ($type == 'http-equiv' && !($document->isHtml5() && $name == 'content-type'))
92 {
93 $buffer .= $tab . '<meta http-equiv="' . $name . '" content="' . htmlspecialchars($content, ENT_COMPAT, 'UTF-8') . '" />' . $lnEnd;
94 }
95 elseif ($type != 'http-equiv' && !empty($content))
96 {
97 $buffer .= $tab . '<meta ' . $type . '="' . $name . '" content="' . htmlspecialchars($content, ENT_COMPAT, 'UTF-8') . '" />' . $lnEnd;
98 }
99 }
100 }
101
102
103 $documentDescription = $document->getDescription();
104
105 if ($documentDescription)
106 {
107 $buffer .= $tab . '<meta name="description" content="' . htmlspecialchars($documentDescription, ENT_COMPAT, 'UTF-8') . '" />' . $lnEnd;
108 }
109
110
111 $generator = $document->getGenerator();
112
113 if ($generator)
114 {
115 $buffer .= $tab . '<meta name="generator" content="' . htmlspecialchars($generator, ENT_COMPAT, 'UTF-8') . '" />' . $lnEnd;
116 }
117
118 $buffer .= $tab . '<title>' . htmlspecialchars($document->getTitle(), ENT_COMPAT, 'UTF-8') . '</title>' . $lnEnd;
119
120
121 foreach ($document->_links as $link => $linkAtrr)
122 {
123 $buffer .= $tab . '<link href="' . $link . '" ' . $linkAtrr['relType'] . '="' . $linkAtrr['relation'] . '"';
124
125 if (is_array($linkAtrr['attribs']))
126 {
127 if ($temp = ArrayHelper::toString($linkAtrr['attribs']))
128 {
129 $buffer .= ' ' . $temp;
130 }
131 }
132
133 $buffer .= ' />' . $lnEnd;
134 }
135
136 $defaultCssMimes = array('text/css');
137
138
139 foreach ($document->_styleSheets as $src => $attribs)
140 {
141
142 $conditional = isset($attribs['options']) && isset($attribs['options']['conditional']) ? $attribs['options']['conditional'] : null;
143
144
145 if (isset($attribs['options']['version']) && $attribs['options']['version'] && strpos($src, '?') === false
146 && ($mediaVersion || $attribs['options']['version'] !== 'auto'))
147 {
148 $src .= '?' . ($attribs['options']['version'] === 'auto' ? $mediaVersion : $attribs['options']['version']);
149 }
150
151 $buffer .= $tab;
152
153
154 if (!is_null($conditional))
155 {
156 $buffer .= '<!--[if ' . $conditional . ']>';
157 }
158
159 $buffer .= '<link href="' . $src . '" rel="stylesheet"';
160
161
162 foreach ($attribs as $attrib => $value)
163 {
164
165 if ($attrib === 'options')
166 {
167 continue;
168 }
169
170
171 if (in_array($attrib, array('type', 'mime')) && $document->isHtml5() && in_array($value, $defaultCssMimes))
172 {
173 continue;
174 }
175
176
177 if ($attrib === 'mime')
178 {
179 $attrib = 'type';
180 }
181
182
183 $buffer .= ' ' . htmlspecialchars($attrib, ENT_COMPAT, 'UTF-8');
184
185
186 $value = !is_scalar($value) ? json_encode($value) : $value;
187
188 $buffer .= '="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"';
189 }
190
191 $buffer .= $tagEnd;
192
193
194 if (!is_null($conditional))
195 {
196 $buffer .= '<![endif]-->';
197 }
198
199 $buffer .= $lnEnd;
200 }
201
202
203 foreach ($document->_style as $type => $content)
204 {
205 $buffer .= $tab . '<style';
206
207 if (!is_null($type) && (!$document->isHtml5() || !in_array($type, $defaultCssMimes)))
208 {
209 $buffer .= ' type="' . $type . '"';
210 }
211
212 $buffer .= '>' . $lnEnd;
213
214
215 if ($document->_mime != 'text/html')
216 {
217 $buffer .= $tab . $tab . '/*<![CDATA[*/' . $lnEnd;
218 }
219
220 $buffer .= $content . $lnEnd;
221
222
223 if ($document->_mime != 'text/html')
224 {
225 $buffer .= $tab . $tab . '/*]]>*/' . $lnEnd;
226 }
227
228 $buffer .= $tab . '</style>' . $lnEnd;
229 }
230
231
232 $scriptOptions = $document->getScriptOptions();
233
234 if (!empty($scriptOptions))
235 {
236 $buffer .= $tab . '<script type="application/json" class="joomla-script-options new">';
237
238 $prettyPrint = (JDEBUG && defined('JSON_PRETTY_PRINT') ? JSON_PRETTY_PRINT : false);
239 $jsonOptions = json_encode($scriptOptions, $prettyPrint);
240 $jsonOptions = $jsonOptions ? $jsonOptions : '{}';
241
242 $buffer .= $jsonOptions;
243 $buffer .= '</script>' . $lnEnd;
244 }
245
246 $defaultJsMimes = array('text/javascript', 'application/javascript', 'text/x-javascript', 'application/x-javascript');
247 $html5NoValueAttributes = array('defer', 'async');
248
249
250 foreach ($document->_scripts as $src => $attribs)
251 {
252
253 $conditional = isset($attribs['options']) && isset($attribs['options']['conditional']) ? $attribs['options']['conditional'] : null;
254
255
256 if (isset($attribs['options']['version']) && $attribs['options']['version'] && strpos($src, '?') === false
257 && ($mediaVersion || $attribs['options']['version'] !== 'auto'))
258 {
259 $src .= '?' . ($attribs['options']['version'] === 'auto' ? $mediaVersion : $attribs['options']['version']);
260 }
261
262 $buffer .= $tab;
263
264
265 if (!is_null($conditional))
266 {
267 $buffer .= '<!--[if ' . $conditional . ']>';
268 }
269
270 $buffer .= '<script src="' . $src . '"';
271
272
273 foreach ($attribs as $attrib => $value)
274 {
275
276 if ($attrib === 'options')
277 {
278 continue;
279 }
280
281
282 if (in_array($attrib, array('type', 'mime')) && $document->isHtml5() && in_array($value, $defaultJsMimes))
283 {
284 continue;
285 }
286
287
288 if (in_array($attrib, array('defer', 'async')) && !$value)
289 {
290 continue;
291 }
292
293
294 if ($attrib === 'mime')
295 {
296 $attrib = 'type';
297 }
298
299 elseif (in_array($attrib, array('defer', 'async')) && $value === true)
300 {
301 $value = $attrib;
302 }
303
304
305 $buffer .= ' ' . htmlspecialchars($attrib, ENT_COMPAT, 'UTF-8');
306
307 if (!($document->isHtml5() && in_array($attrib, $html5NoValueAttributes)))
308 {
309
310 $value = !is_scalar($value) ? json_encode($value) : $value;
311
312 $buffer .= '="' . htmlspecialchars($value, ENT_COMPAT, 'UTF-8') . '"';
313 }
314 }
315
316 $buffer .= '></script>';
317
318
319 if (!is_null($conditional))
320 {
321 $buffer .= '<![endif]-->';
322 }
323
324 $buffer .= $lnEnd;
325 }
326
327
328 foreach ($document->_script as $type => $content)
329 {
330 $buffer .= $tab . '<script';
331
332 if (!is_null($type) && (!$document->isHtml5() || !in_array($type, $defaultJsMimes)))
333 {
334 $buffer .= ' type="' . $type . '"';
335 }
336
337 $buffer .= '>' . $lnEnd;
338
339
340 if ($document->_mime != 'text/html')
341 {
342 $buffer .= $tab . $tab . '//<![CDATA[' . $lnEnd;
343 }
344
345 $buffer .= $content . $lnEnd;
346
347
348 if ($document->_mime != 'text/html')
349 {
350 $buffer .= $tab . $tab . '//]]>' . $lnEnd;
351 }
352
353 $buffer .= $tab . '</script>' . $lnEnd;
354 }
355
356
357 foreach (array_unique($document->_custom) as $custom)
358 {
359 $buffer .= $tab . $custom . $lnEnd;
360 }
361
362 return ltrim($buffer, $tab);
363 }
364 }
365