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