[CLEANUP] TSFE: Deprecate JSfuncCalls for body tag
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / Page / PageGenerator.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Page;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Utility\GeneralUtility;
18 use TYPO3\CMS\Extbase\Service\TypoScriptService;
19 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
20
21 /**
22 * Class for starting TypoScript page generation
23 *
24 * The class is not instantiated as an objects but called directly with the "::" operator.
25 * eg: TSpagegen::pagegenInit()
26 *
27 * @author Kasper Skårhøj <kasperYYYY@typo3.com>
28 */
29 class PageGenerator {
30
31 /**
32 * Do not render title tag
33 * Typoscript setting: [config][noPageTitle]
34 */
35 const NO_PAGE_TITLE = 2;
36
37 /**
38 * Setting some vars in TSFE, primarily based on TypoScript config settings.
39 *
40 * @return void
41 */
42 static public function pagegenInit() {
43 if ($GLOBALS['TSFE']->page['content_from_pid'] > 0) {
44 // make REAL copy of TSFE object - not reference!
45 $temp_copy_TSFE = clone $GLOBALS['TSFE'];
46 // Set ->id to the content_from_pid value - we are going to evaluate this pid as was it a given id for a page-display!
47 $temp_copy_TSFE->id = $GLOBALS['TSFE']->page['content_from_pid'];
48 $temp_copy_TSFE->MP = '';
49 $temp_copy_TSFE->getPageAndRootlineWithDomain($GLOBALS['TSFE']->config['config']['content_from_pid_allowOutsideDomain'] ? 0 : $GLOBALS['TSFE']->domainStartPage);
50 $GLOBALS['TSFE']->contentPid = (int)$temp_copy_TSFE->id;
51 unset($temp_copy_TSFE);
52 }
53 if ($GLOBALS['TSFE']->config['config']['MP_defaults']) {
54 $temp_parts = GeneralUtility::trimExplode('|', $GLOBALS['TSFE']->config['config']['MP_defaults'], TRUE);
55 foreach ($temp_parts as $temp_p) {
56 list($temp_idP, $temp_MPp) = explode(':', $temp_p, 2);
57 $temp_ids = GeneralUtility::intExplode(',', $temp_idP);
58 foreach ($temp_ids as $temp_id) {
59 $GLOBALS['TSFE']->MP_defaults[$temp_id] = $temp_MPp;
60 }
61 }
62 }
63 // Global vars...
64 $GLOBALS['TSFE']->indexedDocTitle = $GLOBALS['TSFE']->page['title'];
65 $GLOBALS['TSFE']->debug = '' . $GLOBALS['TSFE']->config['config']['debug'];
66 // Base url:
67 if (isset($GLOBALS['TSFE']->config['config']['baseURL'])) {
68 $GLOBALS['TSFE']->baseUrl = $GLOBALS['TSFE']->config['config']['baseURL'];
69 $GLOBALS['TSFE']->anchorPrefix = substr(GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'), strlen(GeneralUtility::getIndpEnv('TYPO3_SITE_URL')));
70 }
71 // Internal and External target defaults
72 $GLOBALS['TSFE']->intTarget = '' . $GLOBALS['TSFE']->config['config']['intTarget'];
73 $GLOBALS['TSFE']->extTarget = '' . $GLOBALS['TSFE']->config['config']['extTarget'];
74 $GLOBALS['TSFE']->fileTarget = '' . $GLOBALS['TSFE']->config['config']['fileTarget'];
75 if ($GLOBALS['TSFE']->config['config']['spamProtectEmailAddresses'] === 'ascii') {
76 $GLOBALS['TSFE']->spamProtectEmailAddresses = 'ascii';
77 } else {
78 $GLOBALS['TSFE']->spamProtectEmailAddresses = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($GLOBALS['TSFE']->config['config']['spamProtectEmailAddresses'], -10, 10, 0);
79 }
80 $GLOBALS['TSFE']->absRefPrefix = $GLOBALS['TSFE']->config['config']['absRefPrefix'] ? trim($GLOBALS['TSFE']->config['config']['absRefPrefix']) : '';
81 if ($GLOBALS['TSFE']->type && $GLOBALS['TSFE']->config['config']['frameReloadIfNotInFrameset']) {
82 $tdlLD = $GLOBALS['TSFE']->tmpl->linkData($GLOBALS['TSFE']->page, '_top', $GLOBALS['TSFE']->no_cache, '');
83 $GLOBALS['TSFE']->additionalJavaScript['JSCode'] .= 'if(!parent.' . trim($GLOBALS['TSFE']->sPre) . ' && !parent.view_frame) top.location.href="' . $GLOBALS['TSFE']->baseUrlWrap($tdlLD['totalURL']) . '"';
84 }
85 $GLOBALS['TSFE']->compensateFieldWidth = '' . $GLOBALS['TSFE']->config['config']['compensateFieldWidth'];
86 $GLOBALS['TSFE']->lockFilePath = '' . $GLOBALS['TSFE']->config['config']['lockFilePath'];
87 $GLOBALS['TSFE']->lockFilePath = $GLOBALS['TSFE']->lockFilePath ?: $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'];
88 $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_noScaleUp'] = isset($GLOBALS['TSFE']->config['config']['noScaleUp']) ? '' . $GLOBALS['TSFE']->config['config']['noScaleUp'] : $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_noScaleUp'];
89 $GLOBALS['TSFE']->TYPO3_CONF_VARS['GFX']['im_noScaleUp'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_noScaleUp'];
90 $GLOBALS['TSFE']->ATagParams = trim($GLOBALS['TSFE']->config['config']['ATagParams']) ? ' ' . trim($GLOBALS['TSFE']->config['config']['ATagParams']) : '';
91 if ($GLOBALS['TSFE']->config['config']['setJS_mouseOver']) {
92 $GLOBALS['TSFE']->setJS('mouseOver');
93 }
94 if ($GLOBALS['TSFE']->config['config']['setJS_openPic']) {
95 $GLOBALS['TSFE']->setJS('openPic');
96 }
97 $GLOBALS['TSFE']->sWordRegEx = '';
98 $GLOBALS['TSFE']->sWordList = GeneralUtility::_GP('sword_list');
99 if (is_array($GLOBALS['TSFE']->sWordList)) {
100 $space = !empty($GLOBALS['TSFE']->config['config']['sword_standAlone']) ? '[[:space:]]' : '';
101 foreach ($GLOBALS['TSFE']->sWordList as $val) {
102 if (strlen(trim($val)) > 0) {
103 $GLOBALS['TSFE']->sWordRegEx .= $space . quotemeta($val) . $space . '|';
104 }
105 }
106 $GLOBALS['TSFE']->sWordRegEx = preg_replace('/\\|$/', '', $GLOBALS['TSFE']->sWordRegEx);
107 }
108 // linkVars
109 $GLOBALS['TSFE']->calculateLinkVars();
110 // dtdAllowsFrames indicates whether to use the target attribute in links
111 $GLOBALS['TSFE']->dtdAllowsFrames = FALSE;
112 if ($GLOBALS['TSFE']->config['config']['doctype']) {
113 if (in_array(
114 (string) $GLOBALS['TSFE']->config['config']['doctype'],
115 array('xhtml_trans', 'xhtml_frames', 'xhtml_basic', 'xhtml_2', 'html5'),
116 TRUE)
117 ) {
118 $GLOBALS['TSFE']->dtdAllowsFrames = TRUE;
119 }
120 } else {
121 $GLOBALS['TSFE']->dtdAllowsFrames = TRUE;
122 }
123 // Setting XHTML-doctype from doctype
124 if (!$GLOBALS['TSFE']->config['config']['xhtmlDoctype']) {
125 $GLOBALS['TSFE']->config['config']['xhtmlDoctype'] = $GLOBALS['TSFE']->config['config']['doctype'];
126 }
127 if ($GLOBALS['TSFE']->config['config']['xhtmlDoctype']) {
128 $GLOBALS['TSFE']->xhtmlDoctype = $GLOBALS['TSFE']->config['config']['xhtmlDoctype'];
129 // Checking XHTML-docytpe
130 switch ((string) $GLOBALS['TSFE']->config['config']['xhtmlDoctype']) {
131 case 'xhtml_trans':
132
133 case 'xhtml_strict':
134
135 case 'xhtml_frames':
136 $GLOBALS['TSFE']->xhtmlVersion = 100;
137 break;
138 case 'xhtml_basic':
139 $GLOBALS['TSFE']->xhtmlVersion = 105;
140 break;
141 case 'xhtml_11':
142
143 case 'xhtml+rdfa_10':
144 $GLOBALS['TSFE']->xhtmlVersion = 110;
145 break;
146 case 'xhtml_2':
147 $GLOBALS['TSFE']->xhtmlVersion = 200;
148 break;
149 default:
150 $GLOBALS['TSFE']->getPageRenderer()->setRenderXhtml(FALSE);
151 $GLOBALS['TSFE']->xhtmlDoctype = '';
152 $GLOBALS['TSFE']->xhtmlVersion = 0;
153 }
154 } else {
155 $GLOBALS['TSFE']->getPageRenderer()->setRenderXhtml(FALSE);
156 }
157 }
158
159 /**
160 * Returns an array with files to include. These files are the ones set up in TypoScript config.
161 *
162 * @return array Files to include. Paths are relative to PATH_site.
163 */
164 static public function getIncFiles() {
165 $incFilesArray = array();
166 // Get files from config.includeLibrary
167 $includeLibrary = trim('' . $GLOBALS['TSFE']->config['config']['includeLibrary']);
168 if ($includeLibrary) {
169 $incFile = $GLOBALS['TSFE']->tmpl->getFileName($includeLibrary);
170 if ($incFile) {
171 $incFilesArray[] = $incFile;
172 }
173 }
174 if (is_array($GLOBALS['TSFE']->pSetup['includeLibs.'])) {
175 $incLibs = $GLOBALS['TSFE']->pSetup['includeLibs.'];
176 } else {
177 $incLibs = array();
178 }
179 if (is_array($GLOBALS['TSFE']->tmpl->setup['includeLibs.'])) {
180 // toplevel 'includeLibs' is added to the PAGE.includeLibs. In that way, PAGE-libs get first priority, because if the key already exist, it's not altered. (Due to investigation by me)
181 $incLibs += $GLOBALS['TSFE']->tmpl->setup['includeLibs.'];
182 }
183 if (count($incLibs)) {
184 foreach ($incLibs as $theLib) {
185 if (!is_array($theLib) && ($incFile = $GLOBALS['TSFE']->tmpl->getFileName($theLib))) {
186 $incFilesArray[] = $incFile;
187 }
188 }
189 }
190 return $incFilesArray;
191 }
192
193 /**
194 * Processing JavaScript handlers
195 *
196 * @return array Array with a) a JavaScript section with event handlers and variables set and b) an array with attributes for the body tag.
197 * @deprecated since TYPO3 CMS 7, will be removed in CMS 8, use JS directly
198 */
199 static public function JSeventFunctions() {
200 $functions = array();
201 $setEvents = array();
202 $setBody = array();
203 foreach ($GLOBALS['TSFE']->JSeventFuncCalls as $event => $handlers) {
204 if (count($handlers)) {
205 GeneralUtility::deprecationLog('The usage of $GLOBALS[\'TSFE\']->JSeventFuncCalls is deprecated as of CMS 7. Use Javascript directly.');
206 $functions[] = ' function T3_' . $event . 'Wrapper(e) { ' . implode(' ', $handlers) . ' }';
207 $setEvents[] = ' document.' . $event . '=T3_' . $event . 'Wrapper;';
208 if ($event == 'onload') {
209 // Dubiuos double setting breaks on some browser - do we need it?
210 $setBody[] = 'onload="T3_onloadWrapper();"';
211 }
212 }
213 }
214 return array(count($functions) ? implode(LF, $functions) . LF . implode(LF, $setEvents) : '', $setBody);
215 }
216
217 /**
218 * Rendering the page content
219 *
220 * @return void
221 */
222 static public function renderContent() {
223 // PAGE CONTENT
224 $GLOBALS['TT']->incStackPointer();
225 $GLOBALS['TT']->push($GLOBALS['TSFE']->sPre, 'PAGE');
226 $pageContent = $GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup);
227 if ($GLOBALS['TSFE']->pSetup['wrap']) {
228 $pageContent = $GLOBALS['TSFE']->cObj->wrap($pageContent, $GLOBALS['TSFE']->pSetup['wrap']);
229 }
230 if ($GLOBALS['TSFE']->pSetup['stdWrap.']) {
231 $pageContent = $GLOBALS['TSFE']->cObj->stdWrap($pageContent, $GLOBALS['TSFE']->pSetup['stdWrap.']);
232 }
233 // PAGE HEADER (after content - maybe JS is inserted!
234 // if 'disableAllHeaderCode' is set, all the header-code is discarded!
235 if ($GLOBALS['TSFE']->config['config']['disableAllHeaderCode']) {
236 $GLOBALS['TSFE']->content = $pageContent;
237 } else {
238 self::renderContentWithHeader($pageContent);
239 }
240 $GLOBALS['TT']->pull($GLOBALS['TT']->LR ? $GLOBALS['TSFE']->content : '');
241 $GLOBALS['TT']->decStackPointer();
242 }
243
244 /**
245 * Rendering normal HTML-page with header by wrapping the generated content ($pageContent) in body-tags and setting the header accordingly.
246 *
247 * @param string $pageContent The page content which TypoScript objects has generated
248 * @return void
249 */
250 static public function renderContentWithHeader($pageContent) {
251 /** @var $pageRenderer \TYPO3\CMS\Core\Page\PageRenderer */
252 $pageRenderer = $GLOBALS['TSFE']->getPageRenderer();
253 if ($GLOBALS['TSFE']->config['config']['moveJsFromHeaderToFooter']) {
254 $pageRenderer->enableMoveJsFromHeaderToFooter();
255 }
256 if ($GLOBALS['TSFE']->config['config']['pageRendererTemplateFile']) {
257 $file = $GLOBALS['TSFE']->tmpl->getFileName($GLOBALS['TSFE']->config['config']['pageRendererTemplateFile']);
258 if ($file) {
259 $pageRenderer->setTemplateFile($file);
260 }
261 }
262 $headerComment = $GLOBALS['TSFE']->config['config']['headerComment'];
263 if (trim($headerComment)) {
264 $pageRenderer->addInlineComment(TAB . str_replace(LF, (LF . TAB), trim($headerComment)) . LF);
265 }
266 // Setting charset:
267 $theCharset = $GLOBALS['TSFE']->metaCharset;
268 // Reset the content variables:
269 $GLOBALS['TSFE']->content = '';
270 $htmlTagAttributes = array();
271 $htmlLang = $GLOBALS['TSFE']->config['config']['htmlTag_langKey'] ?: 'en';
272 // Set content direction: (More info: http://www.tau.ac.il/~danon/Hebrew/HTML_and_Hebrew.html)
273 if ($GLOBALS['TSFE']->config['config']['htmlTag_dir']) {
274 $htmlTagAttributes['dir'] = htmlspecialchars($GLOBALS['TSFE']->config['config']['htmlTag_dir']);
275 }
276 // Setting document type:
277 $docTypeParts = array();
278 $xmlDocument = TRUE;
279 // Part 1: XML prologue
280 switch ((string) $GLOBALS['TSFE']->config['config']['xmlprologue']) {
281 case 'none':
282 $xmlDocument = FALSE;
283 $GLOBALS['TSFE']->config['config']['xhtml_cleaning'] = 'none';
284 break;
285 case 'xml_10':
286 $docTypeParts[] = '<?xml version="1.0" encoding="' . $theCharset . '"?>';
287 break;
288 case 'xml_11':
289 $docTypeParts[] = '<?xml version="1.1" encoding="' . $theCharset . '"?>';
290 break;
291 case '':
292 if ($GLOBALS['TSFE']->xhtmlVersion) {
293 $docTypeParts[] = '<?xml version="1.0" encoding="' . $theCharset . '"?>';
294 }
295 break;
296 default:
297 $docTypeParts[] = $GLOBALS['TSFE']->config['config']['xmlprologue'];
298 }
299 // Part 2: DTD
300 $doctype = $GLOBALS['TSFE']->config['config']['doctype'];
301 if ($doctype) {
302 switch ($doctype) {
303 case 'xhtml_trans':
304 $docTypeParts[] = '<!DOCTYPE html
305 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
306 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
307 break;
308 case 'xhtml_strict':
309 $docTypeParts[] = '<!DOCTYPE html
310 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
311 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
312 break;
313 case 'xhtml_frames':
314 $docTypeParts[] = '<!DOCTYPE html
315 PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
316 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
317 break;
318 case 'xhtml_basic':
319 $docTypeParts[] = '<!DOCTYPE html
320 PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"
321 "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">';
322 break;
323 case 'xhtml_11':
324 $docTypeParts[] = '<!DOCTYPE html
325 PUBLIC "-//W3C//DTD XHTML 1.1//EN"
326 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
327 break;
328 case 'xhtml_2':
329 $docTypeParts[] = '<!DOCTYPE html
330 PUBLIC "-//W3C//DTD XHTML 2.0//EN"
331 "http://www.w3.org/TR/xhtml2/DTD/xhtml2.dtd">';
332 break;
333 case 'xhtml+rdfa_10':
334 $docTypeParts[] = '<!DOCTYPE html
335 PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
336 "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">';
337 break;
338 case 'html5':
339 $docTypeParts[] = '<!DOCTYPE html>';
340 if ($xmlDocument) {
341 $pageRenderer->setMetaCharsetTag('<meta charset="|" />');
342 } else {
343 $pageRenderer->setMetaCharsetTag('<meta charset="|">');
344 }
345 break;
346 case 'none':
347 break;
348 default:
349 $docTypeParts[] = $doctype;
350 }
351 } else {
352 $docTypeParts[] = '<!DOCTYPE html>';
353 if ($xmlDocument){
354 $pageRenderer->setMetaCharsetTag('<meta charset="|" />');
355 } else {
356 $pageRenderer->setMetaCharsetTag('<meta charset="|">');
357 }
358 }
359 if ($GLOBALS['TSFE']->xhtmlVersion) {
360 $htmlTagAttributes['xml:lang'] = $htmlLang;
361 }
362 if ($GLOBALS['TSFE']->xhtmlVersion < 110 || $doctype === 'html5') {
363 $htmlTagAttributes['lang'] = $htmlLang;
364 }
365 if ($GLOBALS['TSFE']->xhtmlVersion || $doctype === 'html5' && $xmlDocument) {
366 // We add this to HTML5 to achieve a slightly better backwards compatibility
367 $htmlTagAttributes['xmlns'] = 'http://www.w3.org/1999/xhtml';
368 if (is_array($GLOBALS['TSFE']->config['config']['namespaces.'])) {
369 foreach ($GLOBALS['TSFE']->config['config']['namespaces.'] as $prefix => $uri) {
370 // $uri gets htmlspecialchared later
371 $htmlTagAttributes['xmlns:' . htmlspecialchars($prefix)] = $uri;
372 }
373 }
374 }
375 // Swap XML and doctype order around (for MSIE / Opera standards compliance)
376 if ($GLOBALS['TSFE']->config['config']['doctypeSwitch']) {
377 $docTypeParts = array_reverse($docTypeParts);
378 }
379 // Adding doctype parts:
380 if (count($docTypeParts)) {
381 $pageRenderer->setXmlPrologAndDocType(implode(LF, $docTypeParts));
382 }
383 // Begin header section:
384 if ($GLOBALS['TSFE']->config['config']['htmlTag_setParams'] !== 'none') {
385 $_attr = $GLOBALS['TSFE']->config['config']['htmlTag_setParams'] ? $GLOBALS['TSFE']->config['config']['htmlTag_setParams'] : GeneralUtility::implodeAttributes($htmlTagAttributes);
386 } else {
387 $_attr = '';
388 }
389 $htmlTag = '<html' . ($_attr ? ' ' . $_attr : '') . '>';
390 if (isset($GLOBALS['TSFE']->config['config']['htmlTag_stdWrap.'])) {
391 $htmlTag = $GLOBALS['TSFE']->cObj->stdWrap($htmlTag, $GLOBALS['TSFE']->config['config']['htmlTag_stdWrap.']);
392 }
393 $pageRenderer->setHtmlTag($htmlTag);
394 // Head tag:
395 $headTag = $GLOBALS['TSFE']->pSetup['headTag'] ?: '<head>';
396 $pageRenderer->setHeadTag($headTag);
397 // Setting charset meta tag:
398 $pageRenderer->setCharSet($theCharset);
399 $pageRenderer->addInlineComment(' This website is powered by TYPO3 - inspiring people to share!
400 TYPO3 is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.
401 TYPO3 is copyright ' . TYPO3_copyright_year . ' of Kasper Skaarhoj. Extensions are copyright of their respective owners.
402 Information and contribution at ' . TYPO3_URL_ORG . '
403 ');
404 if ($GLOBALS['TSFE']->baseUrl) {
405 $pageRenderer->setBaseUrl($GLOBALS['TSFE']->baseUrl);
406 }
407 if ($GLOBALS['TSFE']->pSetup['shortcutIcon']) {
408 $favIcon = $GLOBALS['TSFE']->tmpl->getFileName($GLOBALS['TSFE']->pSetup['shortcutIcon']);
409 $iconMimeType = '';
410 if (function_exists('finfo_open')) {
411 if ($finfo = @finfo_open(FILEINFO_MIME)) {
412 $iconMimeType = ' type="' . finfo_file($finfo, (PATH_site . $favIcon)) . '"';
413 finfo_close($finfo);
414 $pageRenderer->setIconMimeType($iconMimeType);
415 }
416 }
417 $pageRenderer->setFavIcon(GeneralUtility::getIndpEnv('TYPO3_SITE_URL') . $favIcon);
418 }
419 // Including CSS files
420 if (is_array($GLOBALS['TSFE']->tmpl->setup['plugin.'])) {
421 $temp_styleLines = array();
422 foreach ($GLOBALS['TSFE']->tmpl->setup['plugin.'] as $key => $iCSScode) {
423 if (is_array($iCSScode)) {
424 if ($iCSScode['_CSS_DEFAULT_STYLE'] && empty($GLOBALS['TSFE']->config['config']['removeDefaultCss'])) {
425 if (isset($iCSScode['_CSS_DEFAULT_STYLE.'])) {
426 $cssDefaultStyle = $GLOBALS['TSFE']->cObj->stdWrap($iCSScode['_CSS_DEFAULT_STYLE'], $iCSScode['_CSS_DEFAULT_STYLE.']);
427 } else {
428 $cssDefaultStyle = $iCSScode['_CSS_DEFAULT_STYLE'];
429 }
430 $temp_styleLines[] = '/* default styles for extension "' . substr($key, 0, -1) . '" */' . LF . $cssDefaultStyle;
431 }
432 if ($iCSScode['_CSS_PAGE_STYLE'] && empty($GLOBALS['TSFE']->config['config']['removePageCss'])) {
433 $cssPageStyle = implode(LF, $iCSScode['_CSS_PAGE_STYLE']);
434 if (isset($iCSScode['_CSS_PAGE_STYLE.'])) {
435 $cssPageStyle = $GLOBALS['TSFE']->cObj->stdWrap($cssPageStyle, $iCSScode['_CSS_PAGE_STYLE.']);
436 }
437 $temp_styleLines[] = '/* specific page styles for extension "' . substr($key, 0, -1) . '" */' . LF . $cssPageStyle;
438 }
439 }
440 }
441 if (count($temp_styleLines)) {
442 if ($GLOBALS['TSFE']->config['config']['inlineStyle2TempFile']) {
443 $pageRenderer->addCssFile(self::inline2TempFile(implode(LF, $temp_styleLines), 'css'));
444 } else {
445 $pageRenderer->addCssInlineBlock('TSFEinlineStyle', implode(LF, $temp_styleLines));
446 }
447 }
448 }
449 if ($GLOBALS['TSFE']->pSetup['stylesheet']) {
450 $ss = $GLOBALS['TSFE']->tmpl->getFileName($GLOBALS['TSFE']->pSetup['stylesheet']);
451 if ($ss) {
452 $pageRenderer->addCssFile($ss);
453 }
454 }
455 /**********************************************************************/
456 /* config.includeCSS / config.includeCSSLibs
457 /**********************************************************************/
458 if (is_array($GLOBALS['TSFE']->pSetup['includeCSS.'])) {
459 foreach ($GLOBALS['TSFE']->pSetup['includeCSS.'] as $key => $CSSfile) {
460 if (!is_array($CSSfile)) {
461 $cssFileConfig = &$GLOBALS['TSFE']->pSetup['includeCSS.'][$key . '.'];
462 if (isset($cssFileConfig['if.']) && !$GLOBALS['TSFE']->cObj->checkIf($cssFileConfig['if.'])) {
463 continue;
464 }
465 $ss = $cssFileConfig['external'] ? $CSSfile : $GLOBALS['TSFE']->tmpl->getFileName($CSSfile);
466 if ($ss) {
467 if ($cssFileConfig['import']) {
468 if (!$cssFileConfig['external'] && $ss[0] !== '/') {
469 // To fix MSIE 6 that cannot handle these as relative paths (according to Ben v Ende)
470 $ss = GeneralUtility::dirname(GeneralUtility::getIndpEnv('SCRIPT_NAME')) . '/' . $ss;
471 }
472 $pageRenderer->addCssInlineBlock('import_' . $key, '@import url("' . htmlspecialchars($ss) . '") ' . htmlspecialchars($cssFileConfig['media']) . ';', empty($cssFileConfig['disableCompression']), $cssFileConfig['forceOnTop'] ? TRUE : FALSE, '');
473 } else {
474 $pageRenderer->addCssFile(
475 $ss,
476 $cssFileConfig['alternate'] ? 'alternate stylesheet' : 'stylesheet',
477 $cssFileConfig['media'] ?: 'all',
478 $cssFileConfig['title'] ?: '',
479 empty($cssFileConfig['disableCompression']),
480 $cssFileConfig['forceOnTop'] ? TRUE : FALSE,
481 $cssFileConfig['allWrap'],
482 $cssFileConfig['excludeFromConcatenation'] ? TRUE : FALSE,
483 $cssFileConfig['allWrap.']['splitChar']
484 );
485 unset($cssFileConfig);
486 }
487 }
488 }
489 }
490 }
491 if (is_array($GLOBALS['TSFE']->pSetup['includeCSSLibs.'])) {
492 foreach ($GLOBALS['TSFE']->pSetup['includeCSSLibs.'] as $key => $CSSfile) {
493 if (!is_array($CSSfile)) {
494 $cssFileConfig = &$GLOBALS['TSFE']->pSetup['includeCSSLibs.'][$key . '.'];
495 if (isset($cssFileConfig['if.']) && !$GLOBALS['TSFE']->cObj->checkIf($cssFileConfig['if.'])) {
496 continue;
497 }
498 $ss = $cssFileConfig['external'] ? $CSSfile : $GLOBALS['TSFE']->tmpl->getFileName($CSSfile);
499 if ($ss) {
500 if ($cssFileConfig['import']) {
501 if (!$cssFileConfig['external'] && $ss[0] !== '/') {
502 // To fix MSIE 6 that cannot handle these as relative paths (according to Ben v Ende)
503 $ss = GeneralUtility::dirname(GeneralUtility::getIndpEnv('SCRIPT_NAME')) . '/' . $ss;
504 }
505 $pageRenderer->addCssInlineBlock('import_' . $key, '@import url("' . htmlspecialchars($ss) . '") ' . htmlspecialchars($cssFileConfig['media']) . ';', empty($cssFileConfig['disableCompression']), $cssFileConfig['forceOnTop'] ? TRUE : FALSE, '');
506 } else {
507 $pageRenderer->addCssLibrary(
508 $ss,
509 $cssFileConfig['alternate'] ? 'alternate stylesheet' : 'stylesheet',
510 $cssFileConfig['media'] ?: 'all',
511 $cssFileConfig['title'] ?: '',
512 empty($cssFileConfig['disableCompression']),
513 $cssFileConfig['forceOnTop'] ? TRUE : FALSE,
514 $cssFileConfig['allWrap'],
515 $cssFileConfig['excludeFromConcatenation'] ? TRUE : FALSE,
516 $cssFileConfig['allWrap.']['splitChar']
517 );
518 unset($cssFileConfig);
519 }
520 }
521 }
522 }
523 }
524
525 // Stylesheets
526 $style = '';
527 if ($GLOBALS['TSFE']->pSetup['insertClassesFromRTE']) {
528 $pageTSConfig = $GLOBALS['TSFE']->getPagesTSconfig();
529 $RTEclasses = $pageTSConfig['RTE.']['classes.'];
530 if (is_array($RTEclasses)) {
531 foreach ($RTEclasses as $RTEclassName => $RTEvalueArray) {
532 if ($RTEvalueArray['value']) {
533 $style .= '
534 .' . substr($RTEclassName, 0, -1) . ' {' . $RTEvalueArray['value'] . '}';
535 }
536 }
537 }
538 if ($GLOBALS['TSFE']->pSetup['insertClassesFromRTE.']['add_mainStyleOverrideDefs'] && is_array($pageTSConfig['RTE.']['default.']['mainStyleOverride_add.'])) {
539 $mSOa_tList = GeneralUtility::trimExplode(',', strtoupper($GLOBALS['TSFE']->pSetup['insertClassesFromRTE.']['add_mainStyleOverrideDefs']), TRUE);
540 foreach ($pageTSConfig['RTE.']['default.']['mainStyleOverride_add.'] as $mSOa_key => $mSOa_value) {
541 if (!is_array($mSOa_value) && (in_array('*', $mSOa_tList) || in_array($mSOa_key, $mSOa_tList))) {
542 $style .= '
543 ' . $mSOa_key . ' {' . $mSOa_value . '}';
544 }
545 }
546 }
547 }
548 // Setting body tag margins in CSS:
549 if (isset($GLOBALS['TSFE']->pSetup['bodyTagMargins']) && $GLOBALS['TSFE']->pSetup['bodyTagMargins.']['useCSS']) {
550 $margins = (int)$GLOBALS['TSFE']->pSetup['bodyTagMargins'];
551 $style .= '
552 BODY {margin: ' . $margins . 'px ' . $margins . 'px ' . $margins . 'px ' . $margins . 'px;}';
553 }
554 if ($GLOBALS['TSFE']->pSetup['adminPanelStyles']) {
555 $style .= '
556
557 /* Default styles for the Admin Panel */
558 TABLE.typo3-adminPanel { border: 1px solid black; background-color: #F6F2E6; }
559 TABLE.typo3-adminPanel TR.typo3-adminPanel-hRow TD { background-color: #9BA1A8; }
560 TABLE.typo3-adminPanel TR.typo3-adminPanel-itemHRow TD { background-color: #ABBBB4; }
561 TABLE.typo3-adminPanel TABLE, TABLE.typo3-adminPanel TD { border: 0px; }
562 TABLE.typo3-adminPanel TD FONT { font-family: verdana; font-size: 10px; color: black; }
563 TABLE.typo3-adminPanel TD A FONT { font-family: verdana; font-size: 10px; color: black; }
564 TABLE.typo3-editPanel { border: 1px solid black; background-color: #F6F2E6; }
565 TABLE.typo3-editPanel TD { border: 0px; }
566 ';
567 }
568 // CSS_inlineStyle from TS
569 $style .= trim($GLOBALS['TSFE']->pSetup['CSS_inlineStyle']);
570 $style .= $GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup['cssInline.'], 'cssInline.');
571 if (trim($style)) {
572 if ($GLOBALS['TSFE']->config['config']['inlineStyle2TempFile']) {
573 $pageRenderer->addCssFile(self::inline2TempFile($style, 'css'));
574 } else {
575 $pageRenderer->addCssInlineBlock('additionalTSFEInlineStyle', $style);
576 }
577 }
578 // Javascript Libraries
579 if (is_array($GLOBALS['TSFE']->pSetup['javascriptLibs.'])) {
580 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['SVG']) {
581 $pageRenderer->loadSvg();
582 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['SVG.']['debug']) {
583 $pageRenderer->enableSvgDebug();
584 }
585 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['SVG.']['forceFlash']) {
586 $pageRenderer->svgForceFlash();
587 }
588 }
589 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['Prototype']) {
590 $pageRenderer->loadPrototype();
591 }
592 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['Scriptaculous']) {
593 $modules = $GLOBALS['TSFE']->pSetup['javascriptLibs.']['Scriptaculous.']['modules'] ?: '';
594 $pageRenderer->loadScriptaculous($modules);
595 }
596 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtCore']) {
597 $pageRenderer->loadExtCore();
598 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtCore.']['debug']) {
599 $pageRenderer->enableExtCoreDebug();
600 }
601 }
602 // Include jQuery into the page renderer
603 if (!empty($GLOBALS['TSFE']->pSetup['javascriptLibs.']['jQuery'])) {
604 $jQueryTS = $GLOBALS['TSFE']->pSetup['javascriptLibs.']['jQuery.'];
605 // Check if version / source is set, if not set variable to "NULL" to use the default of the page renderer
606 $version = isset($jQueryTS['version']) ? $jQueryTS['version'] : NULL;
607 $source = isset($jQueryTS['source']) ? $jQueryTS['source'] : NULL;
608 // When "noConflict" is not set or "1" enable the default jQuery noConflict mode, otherwise disable the namespace
609 if (!isset($jQueryTS['noConflict']) || !empty($jQueryTS['noConflict'])) {
610 // Set namespace to the "noConflict.namespace" value if "noConflict.namespace" has a value
611 if (!empty($jQueryTS['noConflict.']['namespace'])) {
612 $namespace = $jQueryTS['noConflict.']['namespace'];
613 } else {
614 $namespace = \TYPO3\CMS\Core\Page\PageRenderer::JQUERY_NAMESPACE_DEFAULT_NOCONFLICT;
615 }
616 } else {
617 $namespace = \TYPO3\CMS\Core\Page\PageRenderer::JQUERY_NAMESPACE_NONE;
618 }
619 $pageRenderer->loadJQuery($version, $source, $namespace);
620 }
621 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtJs']) {
622 $css = $GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtJs.']['css'] ? TRUE : FALSE;
623 $theme = $GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtJs.']['theme'] ? TRUE : FALSE;
624 $adapter = $GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtJs.']['adapter'] ?: '';
625 $pageRenderer->loadExtJs($css, $theme, $adapter);
626 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtJs.']['debug']) {
627 $pageRenderer->enableExtJsDebug();
628 }
629 if ($GLOBALS['TSFE']->pSetup['javascriptLibs.']['ExtJs.']['quickTips']) {
630 $pageRenderer->enableExtJSQuickTips();
631 }
632 }
633 }
634 // JavaScript library files
635 if (is_array($GLOBALS['TSFE']->pSetup['includeJSlibs.'])) {
636 foreach ($GLOBALS['TSFE']->pSetup['includeJSlibs.'] as $key => $JSfile) {
637 if (!is_array($JSfile)) {
638 if (isset($GLOBALS['TSFE']->pSetup['includeJSlibs.'][$key . '.']['if.']) && !$GLOBALS['TSFE']->cObj->checkIf($GLOBALS['TSFE']->pSetup['includeJSlibs.'][($key . '.')]['if.'])) {
639 continue;
640 }
641 $ss = $GLOBALS['TSFE']->pSetup['includeJSlibs.'][$key . '.']['external'] ? $JSfile : $GLOBALS['TSFE']->tmpl->getFileName($JSfile);
642 if ($ss) {
643 $jsFileConfig = &$GLOBALS['TSFE']->pSetup['includeJSlibs.'][$key . '.'];
644 $type = $jsFileConfig['type'];
645 if (!$type) {
646 $type = 'text/javascript';
647 }
648
649 $pageRenderer->addJsLibrary(
650 $key,
651 $ss,
652 $type,
653 empty($jsFileConfig['disableCompression']),
654 $jsFileConfig['forceOnTop'] ? TRUE : FALSE,
655 $jsFileConfig['allWrap'],
656 $jsFileConfig['excludeFromConcatenation'] ? TRUE : FALSE,
657 $jsFileConfig['allWrap.']['splitChar']
658 );
659 unset($jsFileConfig);
660 }
661 }
662 }
663 }
664 if (is_array($GLOBALS['TSFE']->pSetup['includeJSFooterlibs.'])) {
665 foreach ($GLOBALS['TSFE']->pSetup['includeJSFooterlibs.'] as $key => $JSfile) {
666 if (!is_array($JSfile)) {
667 if (isset($GLOBALS['TSFE']->pSetup['includeJSFooterlibs.'][$key . '.']['if.']) && !$GLOBALS['TSFE']->cObj->checkIf($GLOBALS['TSFE']->pSetup['includeJSFooterlibs.'][($key . '.')]['if.'])) {
668 continue;
669 }
670 $ss = $GLOBALS['TSFE']->pSetup['includeJSFooterlibs.'][$key . '.']['external'] ? $JSfile : $GLOBALS['TSFE']->tmpl->getFileName($JSfile);
671 if ($ss) {
672 $jsFileConfig = &$GLOBALS['TSFE']->pSetup['includeJSFooterlibs.'][$key . '.'];
673 $type = $jsFileConfig['type'];
674 if (!$type) {
675 $type = 'text/javascript';
676 }
677 $pageRenderer->addJsFooterLibrary(
678 $key,
679 $ss,
680 $type,
681 empty($jsFileConfig['disableCompression']),
682 $jsFileConfig['forceOnTop'] ? TRUE : FALSE,
683 $jsFileConfig['allWrap'],
684 $jsFileConfig['excludeFromConcatenation'] ? TRUE : FALSE,
685 $jsFileConfig['allWrap.']['splitChar']
686 );
687 unset($jsFileConfig);
688 }
689 }
690 }
691 }
692 // JavaScript files
693 if (is_array($GLOBALS['TSFE']->pSetup['includeJS.'])) {
694 foreach ($GLOBALS['TSFE']->pSetup['includeJS.'] as $key => $JSfile) {
695 if (!is_array($JSfile)) {
696 if (isset($GLOBALS['TSFE']->pSetup['includeJS.'][$key . '.']['if.']) && !$GLOBALS['TSFE']->cObj->checkIf($GLOBALS['TSFE']->pSetup['includeJS.'][($key . '.')]['if.'])) {
697 continue;
698 }
699 $ss = $GLOBALS['TSFE']->pSetup['includeJS.'][$key . '.']['external'] ? $JSfile : $GLOBALS['TSFE']->tmpl->getFileName($JSfile);
700 if ($ss) {
701 $jsConfig = &$GLOBALS['TSFE']->pSetup['includeJS.'][$key . '.'];
702 $type = $jsConfig['type'];
703 if (!$type) {
704 $type = 'text/javascript';
705 }
706 $pageRenderer->addJsFile(
707 $ss,
708 $type,
709 empty($jsConfig['disableCompression']),
710 $jsConfig['forceOnTop'] ? TRUE : FALSE,
711 $jsConfig['allWrap'],
712 $jsConfig['excludeFromConcatenation'] ? TRUE : FALSE,
713 $jsConfig['allWrap.']['splitChar']
714 );
715 unset($jsConfig);
716 }
717 }
718 }
719 }
720 if (is_array($GLOBALS['TSFE']->pSetup['includeJSFooter.'])) {
721 foreach ($GLOBALS['TSFE']->pSetup['includeJSFooter.'] as $key => $JSfile) {
722 if (!is_array($JSfile)) {
723 if (isset($GLOBALS['TSFE']->pSetup['includeJSFooter.'][$key . '.']['if.']) && !$GLOBALS['TSFE']->cObj->checkIf($GLOBALS['TSFE']->pSetup['includeJSFooter.'][($key . '.')]['if.'])) {
724 continue;
725 }
726 $ss = $GLOBALS['TSFE']->pSetup['includeJSFooter.'][$key . '.']['external'] ? $JSfile : $GLOBALS['TSFE']->tmpl->getFileName($JSfile);
727 if ($ss) {
728 $jsConfig = &$GLOBALS['TSFE']->pSetup['includeJSFooter.'][$key . '.'];
729 $type = $jsConfig['type'];
730 if (!$type) {
731 $type = 'text/javascript';
732 }
733 $pageRenderer->addJsFooterFile(
734 $ss,
735 $type,
736 empty($jsConfig['disableCompression']),
737 $jsConfig['forceOnTop'] ? TRUE : FALSE,
738 $jsConfig['allWrap'],
739 $jsConfig['excludeFromConcatenation'] ? TRUE : FALSE,
740 $jsConfig['allWrap.']['splitChar']
741 );
742 unset($jsConfig);
743 }
744 }
745 }
746 }
747 // Headerdata
748 if (is_array($GLOBALS['TSFE']->pSetup['headerData.'])) {
749 $pageRenderer->addHeaderData($GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup['headerData.'], 'headerData.'));
750 }
751 // Footerdata
752 if (is_array($GLOBALS['TSFE']->pSetup['footerData.'])) {
753 $pageRenderer->addFooterData($GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup['footerData.'], 'footerData.'));
754 }
755 static::generatePageTitle();
756
757 $metaTagsHtml = static::generateMetaTagHtml(
758 isset($GLOBALS['TSFE']->pSetup['meta.']) ? $GLOBALS['TSFE']->pSetup['meta.'] : array(),
759 $GLOBALS['TSFE']->xhtmlVersion,
760 $GLOBALS['TSFE']->cObj
761 );
762 foreach ($metaTagsHtml as $metaTag) {
763 $pageRenderer->addMetaTag($metaTag);
764 }
765
766 unset($GLOBALS['TSFE']->additionalHeaderData['JSCode']);
767 if (is_array($GLOBALS['TSFE']->config['INTincScript'])) {
768 $GLOBALS['TSFE']->additionalHeaderData['JSCode'] = $GLOBALS['TSFE']->JSCode;
769 // Storing the JSCode vars...
770 $GLOBALS['TSFE']->config['INTincScript_ext']['divKey'] = $GLOBALS['TSFE']->uniqueHash();
771 $GLOBALS['TSFE']->config['INTincScript_ext']['additionalHeaderData'] = $GLOBALS['TSFE']->additionalHeaderData;
772 // Storing the header-data array
773 $GLOBALS['TSFE']->config['INTincScript_ext']['additionalFooterData'] = $GLOBALS['TSFE']->additionalFooterData;
774 // Storing the footer-data array
775 $GLOBALS['TSFE']->config['INTincScript_ext']['additionalJavaScript'] = $GLOBALS['TSFE']->additionalJavaScript;
776 // Storing the JS-data array
777 $GLOBALS['TSFE']->config['INTincScript_ext']['additionalCSS'] = $GLOBALS['TSFE']->additionalCSS;
778 // Storing the Style-data array
779 $GLOBALS['TSFE']->additionalHeaderData = array('<!--HD_' . $GLOBALS['TSFE']->config['INTincScript_ext']['divKey'] . '-->');
780 // Clearing the array
781 $GLOBALS['TSFE']->additionalFooterData = array('<!--FD_' . $GLOBALS['TSFE']->config['INTincScript_ext']['divKey'] . '-->');
782 // Clearing the array
783 $GLOBALS['TSFE']->divSection .= '<!--TDS_' . $GLOBALS['TSFE']->config['INTincScript_ext']['divKey'] . '-->';
784 } else {
785 $GLOBALS['TSFE']->INTincScript_loadJSCode();
786 }
787 $JSef = self::JSeventFunctions();
788 $scriptJsCode = $JSef[0];
789
790 if ($GLOBALS['TSFE']->spamProtectEmailAddresses && $GLOBALS['TSFE']->spamProtectEmailAddresses !== 'ascii') {
791 $scriptJsCode = '
792 // decrypt helper function
793 function decryptCharcode(n,start,end,offset) {
794 n = n + offset;
795 if (offset > 0 && n > end) {
796 n = start + (n - end - 1);
797 } else if (offset < 0 && n < start) {
798 n = end - (start - n - 1);
799 }
800 return String.fromCharCode(n);
801 }
802 // decrypt string
803 function decryptString(enc,offset) {
804 var dec = "";
805 var len = enc.length;
806 for(var i=0; i < len; i++) {
807 var n = enc.charCodeAt(i);
808 if (n >= 0x2B && n <= 0x3A) {
809 dec += decryptCharcode(n,0x2B,0x3A,offset); // 0-9 . , - + / :
810 } else if (n >= 0x40 && n <= 0x5A) {
811 dec += decryptCharcode(n,0x40,0x5A,offset); // A-Z @
812 } else if (n >= 0x61 && n <= 0x7A) {
813 dec += decryptCharcode(n,0x61,0x7A,offset); // a-z
814 } else {
815 dec += enc.charAt(i);
816 }
817 }
818 return dec;
819 }
820 // decrypt spam-protected emails
821 function linkTo_UnCryptMailto(s) {
822 location.href = decryptString(s,' . $GLOBALS['TSFE']->spamProtectEmailAddresses * -1 . ');
823 }
824 ';
825 }
826 // Add inline JS
827 $inlineJS = '';
828 // defined in php
829 if (is_array($GLOBALS['TSFE']->inlineJS)) {
830 foreach ($GLOBALS['TSFE']->inlineJS as $key => $val) {
831 if (!is_array($val)) {
832 $inlineJS .= LF . $val . LF;
833 }
834 }
835 }
836 // defined in TS with page.inlineJS
837 // Javascript inline code
838 $inline = $GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup['jsInline.'], 'jsInline.');
839 if ($inline) {
840 $inlineJS .= LF . $inline . LF;
841 }
842 // Javascript inline code for Footer
843 $inlineFooterJs = $GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup['jsFooterInline.'], 'jsFooterInline.');
844 // Should minify?
845 if ($GLOBALS['TSFE']->config['config']['compressJs']) {
846 $pageRenderer->enableCompressJavascript();
847 $minifyErrorScript = ($minifyErrorInline = '');
848 $scriptJsCode = GeneralUtility::minifyJavaScript($scriptJsCode, $minifyErrorScript);
849 if ($minifyErrorScript) {
850 $GLOBALS['TT']->setTSlogMessage($minifyErrorScript, 3);
851 }
852 if ($inlineJS) {
853 $inlineJS = GeneralUtility::minifyJavaScript($inlineJS, $minifyErrorInline);
854 if ($minifyErrorInline) {
855 $GLOBALS['TT']->setTSlogMessage($minifyErrorInline, 3);
856 }
857 }
858 if ($inlineFooterJs) {
859 $inlineFooterJs = GeneralUtility::minifyJavaScript($inlineFooterJs, $minifyErrorInline);
860 if ($minifyErrorInline) {
861 $GLOBALS['TT']->setTSlogMessage($minifyErrorInline, 3);
862 }
863 }
864 }
865 if (!$GLOBALS['TSFE']->config['config']['removeDefaultJS']) {
866 // inlude default and inlineJS
867 if ($scriptJsCode) {
868 $pageRenderer->addJsInlineCode('_scriptCode', $scriptJsCode, $GLOBALS['TSFE']->config['config']['compressJs']);
869 }
870 if ($inlineJS) {
871 $pageRenderer->addJsInlineCode('TS_inlineJS', $inlineJS, $GLOBALS['TSFE']->config['config']['compressJs']);
872 }
873 if ($inlineFooterJs) {
874 $pageRenderer->addJsFooterInlineCode('TS_inlineFooter', $inlineFooterJs, $GLOBALS['TSFE']->config['config']['compressJs']);
875 }
876 } elseif ($GLOBALS['TSFE']->config['config']['removeDefaultJS'] === 'external') {
877 /*
878 * This keeps inlineJS from *_INT Objects from being moved to external files.
879 * At this point in frontend rendering *_INT Objects only have placeholders instead
880 * of actual content so moving these placeholders to external files would
881 * a) break the JS file (syntax errors due to the placeholders)
882 * b) the needed JS would never get included to the page
883 * Therefore inlineJS from *_INT Objects must not be moved to external files but
884 * kept internal.
885 */
886 $inlineJSint = '';
887 self::stripIntObjectPlaceholder($inlineJS, $inlineJSint);
888 if ($inlineJSint) {
889 $pageRenderer->addJsInlineCode('TS_inlineJSint', $inlineJSint, $GLOBALS['TSFE']->config['config']['compressJs']);
890 }
891 if (trim($scriptJsCode . $inlineJS)) {
892 $pageRenderer->addJsFile(self::inline2TempFile($scriptJsCode . $inlineJS, 'js'), 'text/javascript', $GLOBALS['TSFE']->config['config']['compressJs']);
893 }
894 if ($inlineFooterJs) {
895 $inlineFooterJSint = '';
896 self::stripIntObjectPlaceholder($inlineFooterJs, $inlineFooterJSint);
897 if ($inlineFooterJSint) {
898 $pageRenderer->addJsFooterInlineCode('TS_inlineFooterJSint', $inlineFooterJSint, $GLOBALS['TSFE']->config['config']['compressJs']);
899 }
900 $pageRenderer->addJsFooterFile(self::inline2TempFile($inlineFooterJs, 'js'), 'text/javascript', $GLOBALS['TSFE']->config['config']['compressJs']);
901 }
902 } else {
903 // Include only inlineJS
904 if ($inlineJS) {
905 $pageRenderer->addJsInlineCode('TS_inlineJS', $inlineJS, $GLOBALS['TSFE']->config['config']['compressJs']);
906 }
907 if ($inlineFooterJs) {
908 $pageRenderer->addJsFooterInlineCode('TS_inlineFooter', $inlineFooterJs, $GLOBALS['TSFE']->config['config']['compressJs']);
909 }
910 }
911 // ExtJS specific code
912 if (is_array($GLOBALS['TSFE']->pSetup['inlineLanguageLabel.'])) {
913 $pageRenderer->addInlineLanguageLabelArray($GLOBALS['TSFE']->pSetup['inlineLanguageLabel.']);
914 }
915 if (is_array($GLOBALS['TSFE']->pSetup['inlineSettings.'])) {
916 $pageRenderer->addInlineSettingArray('TS', $GLOBALS['TSFE']->pSetup['inlineSettings.']);
917 }
918 if (is_array($GLOBALS['TSFE']->pSetup['extOnReady.'])) {
919 $pageRenderer->addExtOnReadyCode($GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup['extOnReady.'], 'extOnReady.'));
920 }
921 // Compression and concatenate settings
922 if ($GLOBALS['TSFE']->config['config']['compressCss']) {
923 $pageRenderer->enableCompressCss();
924 }
925 if ($GLOBALS['TSFE']->config['config']['compressJs']) {
926 $pageRenderer->enableCompressJavascript();
927 }
928 if ($GLOBALS['TSFE']->config['config']['concatenateCss']) {
929 $pageRenderer->enableConcatenateCss();
930 }
931 if ($GLOBALS['TSFE']->config['config']['concatenateJs']) {
932 $pageRenderer->enableConcatenateJavascript();
933 }
934 // Backward compatibility for old configuration
935 if ($GLOBALS['TSFE']->config['config']['concatenateJsAndCss']) {
936 $pageRenderer->enableConcatenateFiles();
937 }
938 // Add header data block
939 if ($GLOBALS['TSFE']->additionalHeaderData) {
940 $pageRenderer->addHeaderData(implode(LF, $GLOBALS['TSFE']->additionalHeaderData));
941 }
942 // Add footer data block
943 if ($GLOBALS['TSFE']->additionalFooterData) {
944 $pageRenderer->addFooterData(implode(LF, $GLOBALS['TSFE']->additionalFooterData));
945 }
946 // Header complete, now add content
947 if ($GLOBALS['TSFE']->pSetup['frameSet.']) {
948 $fs = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Page\\FramesetRenderer');
949 $pageRenderer->addBodyContent($fs->make($GLOBALS['TSFE']->pSetup['frameSet.']));
950 $pageRenderer->addBodyContent(LF . '<noframes>' . LF);
951 }
952 // Bodytag:
953 if ($GLOBALS['TSFE']->config['config']['disableBodyTag']) {
954 $bodyTag = '';
955 } else {
956 $defBT = $GLOBALS['TSFE']->pSetup['bodyTagCObject'] ? $GLOBALS['TSFE']->cObj->cObjGetSingle($GLOBALS['TSFE']->pSetup['bodyTagCObject'], $GLOBALS['TSFE']->pSetup['bodyTagCObject.'], 'bodyTagCObject') : '';
957 if (!$defBT) {
958 $defBT = $GLOBALS['TSFE']->defaultBodyTag;
959 }
960 $bodyTag = $GLOBALS['TSFE']->pSetup['bodyTag'] ? $GLOBALS['TSFE']->pSetup['bodyTag'] : $defBT;
961 if ($bgImg = $GLOBALS['TSFE']->cObj->getImgResource($GLOBALS['TSFE']->pSetup['bgImg'], $GLOBALS['TSFE']->pSetup['bgImg.'])) {
962 $bodyTag = preg_replace('/>$/', '', trim($bodyTag)) . ' background="' . $GLOBALS['TSFE']->absRefPrefix . $bgImg[3] . '">';
963 }
964 if (isset($GLOBALS['TSFE']->pSetup['bodyTagMargins'])) {
965 $margins = (int)$GLOBALS['TSFE']->pSetup['bodyTagMargins'];
966 if ($GLOBALS['TSFE']->pSetup['bodyTagMargins.']['useCSS']) {
967
968 } else {
969 $bodyTag = preg_replace('/>$/', '', trim($bodyTag)) . ' leftmargin="' . $margins . '" topmargin="' . $margins . '" marginwidth="' . $margins . '" marginheight="' . $margins . '">';
970 }
971 }
972 if (trim($GLOBALS['TSFE']->pSetup['bodyTagAdd'])) {
973 $bodyTag = preg_replace('/>$/', '', trim($bodyTag)) . ' ' . trim($GLOBALS['TSFE']->pSetup['bodyTagAdd']) . '>';
974 }
975 // Event functions
976 if (count($JSef[1])) {
977 $bodyTag = preg_replace('/>$/', '', trim($bodyTag)) . ' ' . trim(implode(' ', $JSef[1])) . '>';
978 }
979 }
980 $pageRenderer->addBodyContent(LF . $bodyTag);
981 // Div-sections
982 if ($GLOBALS['TSFE']->divSection) {
983 $pageRenderer->addBodyContent(LF . $GLOBALS['TSFE']->divSection);
984 }
985 // Page content
986 $pageRenderer->addBodyContent(LF . $pageContent);
987 if (!empty($GLOBALS['TSFE']->config['INTincScript']) && is_array($GLOBALS['TSFE']->config['INTincScript'])) {
988 // Store the serialized pageRenderer in configuration
989 $GLOBALS['TSFE']->config['INTincScript_ext']['pageRenderer'] = serialize($pageRenderer);
990 // Render complete page, keep placeholders for JavaScript and CSS
991 $GLOBALS['TSFE']->content = $pageRenderer->renderPageWithUncachedObjects($GLOBALS['TSFE']->config['INTincScript_ext']['divKey']);
992 } else {
993 // Render complete page
994 $GLOBALS['TSFE']->content = $pageRenderer->render();
995 }
996 // Ending page
997 if ($GLOBALS['TSFE']->pSetup['frameSet.']) {
998 $GLOBALS['TSFE']->content .= LF . '</noframes>';
999 }
1000 }
1001
1002 /*************************
1003 *
1004 * Helper functions
1005 * Remember: Calls internally must still be done on the non-instantiated class: TSpagegen::inline2TempFile()
1006 *
1007 *************************/
1008 /**
1009 * Searches for placeholder created from *_INT cObjects, removes them from
1010 * $searchString and merges them to $intObjects
1011 *
1012 * @param string $searchString The String which should be cleaned from int-object markers
1013 * @param string $intObjects The String the found int-placeholders are moved to (for further processing)
1014 */
1015 static protected function stripIntObjectPlaceholder(&$searchString, &$intObjects) {
1016 $tempArray = array();
1017 preg_match_all('/\\<\\!--INT_SCRIPT.[a-z0-9]*--\\>/', $searchString, $tempArray);
1018 $searchString = preg_replace('/\\<\\!--INT_SCRIPT.[a-z0-9]*--\\>/', '', $searchString);
1019 $intObjects = implode('', $tempArray[0]);
1020 }
1021
1022 /**
1023 * Writes string to a temporary file named after the md5-hash of the string
1024 *
1025 * @param string $str CSS styles / JavaScript to write to file.
1026 * @param string $ext Extension: "css" or "js
1027 * @return string <script> or <link> tag for the file.
1028 */
1029 static public function inline2TempFile($str, $ext) {
1030 // Create filename / tags:
1031 $script = '';
1032 switch ($ext) {
1033 case 'js':
1034 $script = 'typo3temp/javascript_' . substr(md5($str), 0, 10) . '.js';
1035 break;
1036 case 'css':
1037 $script = 'typo3temp/stylesheet_' . substr(md5($str), 0, 10) . '.css';
1038 break;
1039 }
1040 // Write file:
1041 if ($script) {
1042 if (!@is_file((PATH_site . $script))) {
1043 GeneralUtility::writeFile(PATH_site . $script, $str);
1044 }
1045 }
1046 return $script;
1047 }
1048
1049 /**
1050 * Checks if the value defined in "config.linkVars" contains an allowed value. Otherwise, return FALSE which means the value will not be added to any links.
1051 *
1052 * @param string $haystack The string in which to find $needle
1053 * @param string $needle The string to find in $haystack
1054 * @return boolean Returns TRUE if $needle matches or is found in $haystack
1055 */
1056 static public function isAllowedLinkVarValue($haystack, $needle) {
1057 $OK = FALSE;
1058 // Integer
1059 if ($needle == 'int' || $needle == 'integer') {
1060 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($haystack)) {
1061 $OK = TRUE;
1062 }
1063 } elseif (preg_match('/^\\/.+\\/[imsxeADSUXu]*$/', $needle)) {
1064 // Regular expression, only "//" is allowed as delimiter
1065 if (@preg_match($needle, $haystack)) {
1066 $OK = TRUE;
1067 }
1068 } elseif (strstr($needle, '-')) {
1069 // Range
1070 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($haystack)) {
1071 $range = explode('-', $needle);
1072 if ($range[0] <= $haystack && $range[1] >= $haystack) {
1073 $OK = TRUE;
1074 }
1075 }
1076 } elseif (strstr($needle, '|')) {
1077 // List
1078 // Trim the input
1079 $haystack = str_replace(' ', '', $haystack);
1080 if (strstr('|' . $needle . '|', '|' . $haystack . '|')) {
1081 $OK = TRUE;
1082 }
1083 } elseif ((string)$needle === (string)$haystack) {
1084 // String comparison
1085 $OK = TRUE;
1086 }
1087 return $OK;
1088 }
1089
1090 /**
1091 * Generate title for page.
1092 * Takes the settings ['config']['noPageTitle'], ['config']['pageTitleFirst'], ['config']['titleTagFunction']
1093 * and ['config']['noPageTitle'] into account.
1094 * Furthermore $GLOBALS['TSFE']->altPageTitle is observed.
1095 *
1096 * @return void
1097 */
1098 static public function generatePageTitle() {
1099 $titleTagContent = $GLOBALS['TSFE']->tmpl->printTitle(
1100 $GLOBALS['TSFE']->altPageTitle ? $GLOBALS['TSFE']->altPageTitle : $GLOBALS['TSFE']->page['title'],
1101 $GLOBALS['TSFE']->config['config']['noPageTitle'],
1102 $GLOBALS['TSFE']->config['config']['pageTitleFirst']
1103 );
1104 if ($GLOBALS['TSFE']->config['config']['titleTagFunction']) {
1105 $titleTagContent = $GLOBALS['TSFE']->cObj->callUserFunction(
1106 $GLOBALS['TSFE']->config['config']['titleTagFunction'],
1107 array(),
1108 $titleTagContent
1109 );
1110 }
1111 if ($titleTagContent !== '' && (int)$GLOBALS['TSFE']->config['config']['noPageTitle'] !== self::NO_PAGE_TITLE) {
1112 $GLOBALS['TSFE']->getPageRenderer()->setTitle($titleTagContent);
1113 }
1114 }
1115
1116 /**
1117 * Generate meta tags from meta tag TypoScript
1118 *
1119 * @param array $metaTagTypoScript TypoScript configuration for meta tags (e.g. $GLOBALS['TSFE']->pSetup['meta.'])
1120 * @param bool $xhtml Whether xhtml tag-style should be used. (e.g. pass $GLOBALS['TSFE']->xhtmlVersion here)
1121 * @param ContentObjectRenderer $cObj
1122 * @return array Array of HTML meta tags
1123 */
1124 static protected function generateMetaTagHtml(array $metaTagTypoScript, $xhtml, ContentObjectRenderer $cObj) {
1125 // Add ending slash only to documents rendered as xhtml
1126 $endingSlash = $xhtml ? ' /' : '';
1127
1128 $metaTags = array(
1129 '<meta name="generator" content="TYPO3 ' . TYPO3_branch . ' CMS"' . $endingSlash . '>'
1130 );
1131
1132 /** @var TypoScriptService $typoScriptService */
1133 $typoScriptService = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Service\\TypoScriptService');
1134 $conf = $typoScriptService->convertTypoScriptArrayToPlainArray($metaTagTypoScript);
1135 foreach ($conf as $key => $properties) {
1136 if (is_array($properties)) {
1137 $nodeValue = isset($properties['_typoScriptNodeValue']) ? $properties['_typoScriptNodeValue'] : '';
1138 $value = trim($cObj->stdWrap($nodeValue, $metaTagTypoScript[$key . '.']));
1139 } else {
1140 $value = $properties;
1141 }
1142 if ($value !== '') {
1143 $attribute = 'name';
1144 if ( (is_array($properties) && !empty($properties['httpEquivalent'])) || strtolower($key) === 'refresh') {
1145 $attribute = 'http-equiv';
1146 }
1147 $metaTags[] = '<meta ' . $attribute . '="' . $key . '" content="' . htmlspecialchars($value) . '"' . $endingSlash . '>';
1148 }
1149 }
1150 return $metaTags;
1151 }
1152 }