TYPO3 CMS  TYPO3_8-7
PageGenerator.php
Go to the documentation of this file.
1 <?php
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 
26 
34 {
39  const NO_PAGE_TITLE = 2;
40 
46  public static function pagegenInit()
47  {
50  $tsfe = $GLOBALS['TSFE'];
51  if ($tsfe->page['content_from_pid'] > 0) {
52  // make REAL copy of TSFE object - not reference!
53  $temp_copy_TSFE = clone $tsfe;
54  // 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!
55  $temp_copy_TSFE->id = $tsfe->page['content_from_pid'];
56  $temp_copy_TSFE->MP = '';
57  $temp_copy_TSFE->getPageAndRootlineWithDomain($tsfe->config['config']['content_from_pid_allowOutsideDomain'] ? 0 : $tsfe->domainStartPage);
58  $tsfe->contentPid = (int)$temp_copy_TSFE->id;
59  unset($temp_copy_TSFE);
60  }
61  if ($tsfe->config['config']['MP_defaults']) {
62  $temp_parts = GeneralUtility::trimExplode('|', $tsfe->config['config']['MP_defaults'], true);
63  foreach ($temp_parts as $temp_p) {
64  list($temp_idP, $temp_MPp) = explode(':', $temp_p, 2);
65  $temp_ids = GeneralUtility::intExplode(',', $temp_idP);
66  foreach ($temp_ids as $temp_id) {
67  $tsfe->MP_defaults[$temp_id] = $temp_MPp;
68  }
69  }
70  }
71  // Global vars...
72  $tsfe->indexedDocTitle = $tsfe->page['title'];
73  $tsfe->debug = !empty($tsfe->config['config']['debug']);
74  // Base url:
75  if (isset($tsfe->config['config']['baseURL'])) {
76  $tsfe->baseUrl = $tsfe->config['config']['baseURL'];
77  }
78  // Internal and External target defaults
79  $tsfe->intTarget = '' . $tsfe->config['config']['intTarget'];
80  $tsfe->extTarget = '' . $tsfe->config['config']['extTarget'];
81  $tsfe->fileTarget = '' . $tsfe->config['config']['fileTarget'];
82  if ($tsfe->config['config']['spamProtectEmailAddresses'] === 'ascii') {
83  $tsfe->spamProtectEmailAddresses = 'ascii';
84  } else {
85  $tsfe->spamProtectEmailAddresses = MathUtility::forceIntegerInRange($tsfe->config['config']['spamProtectEmailAddresses'], -10, 10, 0);
86  }
87  // calculate the absolute path prefix
88  if (!empty($tsfe->config['config']['absRefPrefix'])) {
89  $absRefPrefix = trim($tsfe->config['config']['absRefPrefix']);
90  if ($absRefPrefix === 'auto') {
91  $tsfe->absRefPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
92  } else {
93  $tsfe->absRefPrefix = $absRefPrefix;
94  }
95  } else {
96  $tsfe->absRefPrefix = '';
97  }
98  if ($tsfe->type && $tsfe->config['config']['frameReloadIfNotInFrameset']) {
100  'frameReloadIfNotInFrameset has been marked as deprecated since TYPO3 v8, ' .
101  'and will be removed in TYPO3 v9.'
102  );
103  $tdlLD = $tsfe->tmpl->linkData($tsfe->page, '_top', $tsfe->no_cache, '');
104  $tsfe->additionalJavaScript['JSCode'] .= 'if(!parent.' . trim($tsfe->sPre) . ' && !parent.view_frame) top.location.href="' . $tsfe->baseUrlWrap($tdlLD['totalURL']) . '"';
105  }
106  $tsfe->compensateFieldWidth = '' . $tsfe->config['config']['compensateFieldWidth'];
107  $tsfe->lockFilePath = '' . $tsfe->config['config']['lockFilePath'];
108  $tsfe->lockFilePath = $tsfe->lockFilePath ?: $GLOBALS['TYPO3_CONF_VARS']['BE']['fileadminDir'];
109  if (isset($tsfe->config['config']['noScaleUp'])) {
110  GeneralUtility::deprecationLog('The TypoScript property "config.noScaleUp" is deprecated since TYPO3 v8 and will be removed in TYPO3 v9. Please use the global TYPO3 configuration setting "GFX/processor_allowUpscaling" instead.');
111  }
112  $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_allowUpscaling'] = (bool)(isset($tsfe->config['config']['noScaleUp']) ? !$tsfe->config['config']['noScaleUp'] : $GLOBALS['TYPO3_CONF_VARS']['GFX']['processor_allowUpscaling']);
113  $tsfe->ATagParams = trim($tsfe->config['config']['ATagParams']) ? ' ' . trim($tsfe->config['config']['ATagParams']) : '';
114  if ($tsfe->config['config']['setJS_mouseOver']) {
115  $tsfe->logDeprecatedTyposcript(
116  'config.setJS_mouseOver',
117  'The TypoScript property "config.setJS_mouseOver" is deprecated since TYPO3 v8 and will be removed in TYPO3 v9. Please include the JavaScript snippet directly via TypoScript page.jsInline.'
118  );
119  $tsfe->setJS('mouseOver');
120  }
121  if ($tsfe->config['config']['setJS_openPic']) {
122  $tsfe->logDeprecatedTyposcript(
123  'config.setJS_openPic',
124  'The TypoScript property "config.setJS_openPic" is deprecated since TYPO3 v8 and will be removed in TYPO3 v9. Please include the JavaScript snippet directly via TypoScript page.jsInline.'
125  );
126  $tsfe->setJS('openPic');
127  }
128  static::initializeSearchWordDataInTsfe();
129  // linkVars
130  $tsfe->calculateLinkVars();
131  // dtdAllowsFrames indicates whether to use the target attribute in links
132  $tsfe->dtdAllowsFrames = false;
133  if ($tsfe->config['config']['doctype']) {
134  if (in_array(
135  (string)$tsfe->config['config']['doctype'],
136  ['xhtml_trans', 'xhtml_frames', 'xhtml_basic', 'html5'],
137  true
138  )
139  ) {
140  $tsfe->dtdAllowsFrames = true;
141  }
142  } else {
143  $tsfe->dtdAllowsFrames = true;
144  }
145  // Setting XHTML-doctype from doctype
146  if (!$tsfe->config['config']['xhtmlDoctype']) {
147  $tsfe->config['config']['xhtmlDoctype'] = $tsfe->config['config']['doctype'];
148  }
149  if ($tsfe->config['config']['xhtmlDoctype']) {
150  $tsfe->xhtmlDoctype = $tsfe->config['config']['xhtmlDoctype'];
151  // Checking XHTML-docytpe
152  switch ((string)$tsfe->config['config']['xhtmlDoctype']) {
153  case 'xhtml_trans':
154  case 'xhtml_strict':
155  $tsfe->xhtmlVersion = 100;
156  break;
157  case 'xhtml_frames':
159  'xhtmlDoctype = xhtml_frames and doctype = xhtml_frames have been marked as deprecated since TYPO3 v8, ' .
160  'and will be removed in TYPO3 v9.'
161  );
162  $tsfe->xhtmlVersion = 100;
163  break;
164  case 'xhtml_basic':
165  $tsfe->xhtmlVersion = 105;
166  break;
167  case 'xhtml_11':
168  case 'xhtml+rdfa_10':
169  $tsfe->xhtmlVersion = 110;
170  break;
171  default:
172  static::getPageRenderer()->setRenderXhtml(false);
173  $tsfe->xhtmlDoctype = '';
174  $tsfe->xhtmlVersion = 0;
175  }
176  } else {
177  static::getPageRenderer()->setRenderXhtml(false);
178  }
179  }
180 
184  public static function renderContent()
185  {
187  $tsfe = $GLOBALS['TSFE'];
188 
190  $timeTracker = GeneralUtility::makeInstance(TimeTracker::class);
191 
192  // PAGE CONTENT
193  $timeTracker->incStackPointer();
194  $timeTracker->push($tsfe->sPre, 'PAGE');
195  $pageContent = $tsfe->cObj->cObjGet($tsfe->pSetup);
196  if ($tsfe->pSetup['wrap']) {
197  $pageContent = $tsfe->cObj->wrap($pageContent, $tsfe->pSetup['wrap']);
198  }
199  if ($tsfe->pSetup['stdWrap.']) {
200  $pageContent = $tsfe->cObj->stdWrap($pageContent, $tsfe->pSetup['stdWrap.']);
201  }
202  // PAGE HEADER (after content - maybe JS is inserted!
203  // if 'disableAllHeaderCode' is set, all the header-code is discarded!
204  if ($tsfe->config['config']['disableAllHeaderCode']) {
205  $tsfe->content = $pageContent;
206  } else {
207  self::renderContentWithHeader($pageContent);
208  }
209  $timeTracker->pull($timeTracker->LR ? $tsfe->content : '');
210  $timeTracker->decStackPointer();
211  }
212 
218  public static function renderContentWithHeader($pageContent)
219  {
221  $tsfe = $GLOBALS['TSFE'];
222 
224  $timeTracker = GeneralUtility::makeInstance(TimeTracker::class);
225 
226  $pageRenderer = static::getPageRenderer();
227  if ($tsfe->config['config']['moveJsFromHeaderToFooter']) {
228  $pageRenderer->enableMoveJsFromHeaderToFooter();
229  }
230  if ($tsfe->config['config']['pageRendererTemplateFile']) {
231  $file = $tsfe->tmpl->getFileName($tsfe->config['config']['pageRendererTemplateFile']);
232  if ($file) {
233  $pageRenderer->setTemplateFile($file);
234  }
235  }
236  $headerComment = $tsfe->config['config']['headerComment'];
237  if (trim($headerComment)) {
238  $pageRenderer->addInlineComment(TAB . str_replace(LF, (LF . TAB), trim($headerComment)) . LF);
239  }
240  // Setting charset:
241  $theCharset = $tsfe->metaCharset;
242  // Reset the content variables:
243  $tsfe->content = '';
244  $htmlTagAttributes = [];
245  $htmlLang = $tsfe->config['config']['htmlTag_langKey'] ?: ($tsfe->sys_language_isocode ?: 'en');
246  // Set content direction: (More info: http://www.tau.ac.il/~danon/Hebrew/HTML_and_Hebrew.html)
247  if ($tsfe->config['config']['htmlTag_dir']) {
248  $htmlTagAttributes['dir'] = htmlspecialchars($tsfe->config['config']['htmlTag_dir']);
249  }
250  // Setting document type:
251  $docTypeParts = [];
252  $xmlDocument = true;
253  // Part 1: XML prologue
254  switch ((string)$tsfe->config['config']['xmlprologue']) {
255  case 'none':
256  $xmlDocument = false;
257  break;
258  case 'xml_10':
259  $docTypeParts[] = '<?xml version="1.0" encoding="' . $theCharset . '"?>';
260  break;
261  case 'xml_11':
262  $docTypeParts[] = '<?xml version="1.1" encoding="' . $theCharset . '"?>';
263  break;
264  case '':
265  if ($tsfe->xhtmlVersion) {
266  $docTypeParts[] = '<?xml version="1.0" encoding="' . $theCharset . '"?>';
267  } else {
268  $xmlDocument = false;
269  }
270  break;
271  default:
272  $docTypeParts[] = $tsfe->config['config']['xmlprologue'];
273  }
274  // Part 2: DTD
275  $doctype = $tsfe->config['config']['doctype'];
276  if ($doctype) {
277  switch ($doctype) {
278  case 'xhtml_trans':
279  $docTypeParts[] = '<!DOCTYPE html
280  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
281  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
282  break;
283  case 'xhtml_strict':
284  $docTypeParts[] = '<!DOCTYPE html
285  PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
286  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
287  break;
288  case 'xhtml_frames':
289  $docTypeParts[] = '<!DOCTYPE html
290  PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
291  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
292  break;
293  case 'xhtml_basic':
294  $docTypeParts[] = '<!DOCTYPE html
295  PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"
296  "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">';
297  break;
298  case 'xhtml_11':
299  $docTypeParts[] = '<!DOCTYPE html
300  PUBLIC "-//W3C//DTD XHTML 1.1//EN"
301  "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
302  break;
303  case 'xhtml+rdfa_10':
304  $docTypeParts[] = '<!DOCTYPE html
305  PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
306  "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">';
307  break;
308  case 'html5':
309  $docTypeParts[] = '<!DOCTYPE html>';
310  if ($xmlDocument) {
311  $pageRenderer->setMetaCharsetTag('<meta charset="|" />');
312  } else {
313  $pageRenderer->setMetaCharsetTag('<meta charset="|">');
314  }
315  break;
316  case 'none':
317  break;
318  default:
319  $docTypeParts[] = $doctype;
320  }
321  } else {
322  $docTypeParts[] = '<!DOCTYPE html>';
323  if ($xmlDocument) {
324  $pageRenderer->setMetaCharsetTag('<meta charset="|" />');
325  } else {
326  $pageRenderer->setMetaCharsetTag('<meta charset="|">');
327  }
328  }
329  if ($tsfe->xhtmlVersion) {
330  $htmlTagAttributes['xml:lang'] = $htmlLang;
331  }
332  if ($tsfe->xhtmlVersion < 110 || $doctype === 'html5') {
333  $htmlTagAttributes['lang'] = $htmlLang;
334  }
335  if ($tsfe->xhtmlVersion || $doctype === 'html5' && $xmlDocument) {
336  // We add this to HTML5 to achieve a slightly better backwards compatibility
337  $htmlTagAttributes['xmlns'] = 'http://www.w3.org/1999/xhtml';
338  if (is_array($tsfe->config['config']['namespaces.'])) {
339  foreach ($tsfe->config['config']['namespaces.'] as $prefix => $uri) {
340  // $uri gets htmlspecialchared later
341  $htmlTagAttributes['xmlns:' . htmlspecialchars($prefix)] = $uri;
342  }
343  }
344  }
345  // Swap XML and doctype order around (for MSIE / Opera standards compliance)
346  if ($tsfe->config['config']['doctypeSwitch']) {
347  $docTypeParts = array_reverse($docTypeParts);
348  }
349  // Adding doctype parts:
350  if (!empty($docTypeParts)) {
351  $pageRenderer->setXmlPrologAndDocType(implode(LF, $docTypeParts));
352  }
353  // Begin header section:
354  if ($tsfe->config['config']['htmlTag_setParams'] !== 'none') {
355  $_attr = $tsfe->config['config']['htmlTag_setParams'] ? $tsfe->config['config']['htmlTag_setParams'] : GeneralUtility::implodeAttributes($htmlTagAttributes);
356  } else {
357  $_attr = '';
358  }
359  $htmlTag = '<html' . ($_attr ? ' ' . $_attr : '') . '>';
360  if (isset($tsfe->config['config']['htmlTag_stdWrap.'])) {
361  $htmlTag = $tsfe->cObj->stdWrap($htmlTag, $tsfe->config['config']['htmlTag_stdWrap.']);
362  }
363  $pageRenderer->setHtmlTag($htmlTag);
364  // Head tag:
365  $headTag = $tsfe->pSetup['headTag'] ?: '<head>';
366  if (isset($tsfe->pSetup['headTag.'])) {
367  $headTag = $tsfe->cObj->stdWrap($headTag, $tsfe->pSetup['headTag.']);
368  }
369  $pageRenderer->setHeadTag($headTag);
370  // Setting charset meta tag:
371  $pageRenderer->setCharSet($theCharset);
372  $pageRenderer->addInlineComment(' This website is powered by TYPO3 - inspiring people to share!
373  TYPO3 is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.
374  TYPO3 is copyright ' . TYPO3_copyright_year . ' of Kasper Skaarhoj. Extensions are copyright of their respective owners.
375  Information and contribution at ' . TYPO3_URL_GENERAL . '
376 ');
377  if ($tsfe->baseUrl) {
378  $pageRenderer->setBaseUrl($tsfe->baseUrl);
379  }
380  if ($tsfe->pSetup['shortcutIcon']) {
381  $favIcon = ltrim($tsfe->tmpl->getFileName($tsfe->pSetup['shortcutIcon']), '/');
382  $iconFileInfo = GeneralUtility::makeInstance(ImageInfo::class, PATH_site . $favIcon);
383  if ($iconFileInfo->isFile()) {
384  $iconMimeType = $iconFileInfo->getMimeType();
385  if ($iconMimeType) {
386  $iconMimeType = ' type="' . $iconMimeType . '"';
387  $pageRenderer->setIconMimeType($iconMimeType);
388  }
389  $pageRenderer->setFavIcon(PathUtility::getAbsoluteWebPath($tsfe->absRefPrefix . $favIcon));
390  }
391  }
392  // Including CSS files
393  if (is_array($tsfe->tmpl->setup['plugin.'])) {
394  $stylesFromPlugins = '';
395  foreach ($tsfe->tmpl->setup['plugin.'] as $key => $iCSScode) {
396  if (is_array($iCSScode)) {
397  if ($iCSScode['_CSS_DEFAULT_STYLE'] && empty($tsfe->config['config']['removeDefaultCss'])) {
398  if (isset($iCSScode['_CSS_DEFAULT_STYLE.'])) {
399  $cssDefaultStyle = $tsfe->cObj->stdWrap($iCSScode['_CSS_DEFAULT_STYLE'], $iCSScode['_CSS_DEFAULT_STYLE.']);
400  } else {
401  $cssDefaultStyle = $iCSScode['_CSS_DEFAULT_STYLE'];
402  }
403  $stylesFromPlugins .= '/* default styles for extension "' . substr($key, 0, -1) . '" */' . LF . $cssDefaultStyle . LF;
404  }
405  if ($iCSScode['_CSS_PAGE_STYLE'] && empty($tsfe->config['config']['removePageCss'])) {
406  $cssPageStyle = implode(LF, $iCSScode['_CSS_PAGE_STYLE']);
407  if (isset($iCSScode['_CSS_PAGE_STYLE.'])) {
408  $cssPageStyle = $tsfe->cObj->stdWrap($cssPageStyle, $iCSScode['_CSS_PAGE_STYLE.']);
409  }
410  $cssPageStyle = '/* specific page styles for extension "' . substr($key, 0, -1) . '" */' . LF . $cssPageStyle;
411  self::addCssToPageRenderer($cssPageStyle, true, 'InlinePageCss');
412  }
413  }
414  }
415  if (!empty($stylesFromPlugins)) {
416  self::addCssToPageRenderer($stylesFromPlugins, false, 'InlineDefaultCss');
417  }
418  }
419  if ($tsfe->pSetup['stylesheet']) {
420  $ss = $tsfe->tmpl->getFileName($tsfe->pSetup['stylesheet']);
421  if ($ss) {
422  $pageRenderer->addCssFile($ss);
423  }
424  }
425  /**********************************************************************/
426  /* config.includeCSS / config.includeCSSLibs
427  /**********************************************************************/
428  if (is_array($tsfe->pSetup['includeCSS.'])) {
429  foreach ($tsfe->pSetup['includeCSS.'] as $key => $CSSfile) {
430  if (!is_array($CSSfile)) {
431  $cssFileConfig = &$tsfe->pSetup['includeCSS.'][$key . '.'];
432  if (isset($cssFileConfig['if.']) && !$tsfe->cObj->checkIf($cssFileConfig['if.'])) {
433  continue;
434  }
435  $ss = $cssFileConfig['external'] ? $CSSfile : $tsfe->tmpl->getFileName($CSSfile);
436  if ($ss) {
437  if ($cssFileConfig['import']) {
438  if (!$cssFileConfig['external'] && $ss[0] !== '/') {
439  // To fix MSIE 6 that cannot handle these as relative paths (according to Ben v Ende)
440  $ss = GeneralUtility::dirname(GeneralUtility::getIndpEnv('SCRIPT_NAME')) . '/' . $ss;
441  }
442  $pageRenderer->addCssInlineBlock('import_' . $key, '@import url("' . htmlspecialchars($ss) . '") ' . htmlspecialchars($cssFileConfig['media']) . ';', empty($cssFileConfig['disableCompression']), (bool)$cssFileConfig['forceOnTop']);
443  } else {
444  $pageRenderer->addCssFile(
445  $ss,
446  $cssFileConfig['alternate'] ? 'alternate stylesheet' : 'stylesheet',
447  $cssFileConfig['media'] ?: 'all',
448  $cssFileConfig['title'] ?: '',
449  empty($cssFileConfig['disableCompression']),
450  (bool)$cssFileConfig['forceOnTop'],
451  $cssFileConfig['allWrap'],
452  (bool)$cssFileConfig['excludeFromConcatenation'],
453  $cssFileConfig['allWrap.']['splitChar']
454  );
455  unset($cssFileConfig);
456  }
457  }
458  }
459  }
460  }
461  if (is_array($tsfe->pSetup['includeCSSLibs.'])) {
462  foreach ($tsfe->pSetup['includeCSSLibs.'] as $key => $CSSfile) {
463  if (!is_array($CSSfile)) {
464  $cssFileConfig = &$tsfe->pSetup['includeCSSLibs.'][$key . '.'];
465  if (isset($cssFileConfig['if.']) && !$tsfe->cObj->checkIf($cssFileConfig['if.'])) {
466  continue;
467  }
468  $ss = $cssFileConfig['external'] ? $CSSfile : $tsfe->tmpl->getFileName($CSSfile);
469  if ($ss) {
470  if ($cssFileConfig['import']) {
471  if (!$cssFileConfig['external'] && $ss[0] !== '/') {
472  // To fix MSIE 6 that cannot handle these as relative paths (according to Ben v Ende)
473  $ss = GeneralUtility::dirname(GeneralUtility::getIndpEnv('SCRIPT_NAME')) . '/' . $ss;
474  }
475  $pageRenderer->addCssInlineBlock('import_' . $key, '@import url("' . htmlspecialchars($ss) . '") ' . htmlspecialchars($cssFileConfig['media']) . ';', empty($cssFileConfig['disableCompression']), (bool)$cssFileConfig['forceOnTop']);
476  } else {
477  $pageRenderer->addCssLibrary(
478  $ss,
479  $cssFileConfig['alternate'] ? 'alternate stylesheet' : 'stylesheet',
480  $cssFileConfig['media'] ?: 'all',
481  $cssFileConfig['title'] ?: '',
482  empty($cssFileConfig['disableCompression']),
483  (bool)$cssFileConfig['forceOnTop'],
484  $cssFileConfig['allWrap'],
485  (bool)$cssFileConfig['excludeFromConcatenation'],
486  $cssFileConfig['allWrap.']['splitChar']
487  );
488  unset($cssFileConfig);
489  }
490  }
491  }
492  }
493  }
494 
495  // Stylesheets
496  $style = '';
497  if ($tsfe->pSetup['insertClassesFromRTE']) {
498  $tsfe->logDeprecatedTyposcript(
499  'page.insertClassesFromRTE',
500  'Loading CSS classes from the RTE directly is discouraged in TYPO3 v8, as CSS classes should be '
501  . 'defined in CSS/LESS/SASS files instead, ensuring to load only what is necessary for a page, and '
502  . 'speeding up page rendering ("above the fold"). Additionally CSS should be defined in CSS files or '
503  . 'TypoScript and not via magic of pageTSconfig, overlaid by userTSconfig.'
504  );
505  $pageTSConfig = $tsfe->getPagesTSconfig();
506  $RTEclasses = $pageTSConfig['RTE.']['classes.'];
507  if (is_array($RTEclasses)) {
508  foreach ($RTEclasses as $RTEclassName => $RTEvalueArray) {
509  if ($RTEvalueArray['value']) {
510  $style .= '
511 .' . substr($RTEclassName, 0, -1) . ' {' . $RTEvalueArray['value'] . '}';
512  }
513  }
514  }
515  if ($tsfe->pSetup['insertClassesFromRTE.']['add_mainStyleOverrideDefs'] && is_array($pageTSConfig['RTE.']['default.']['mainStyleOverride_add.'])) {
516  $mSOa_tList = GeneralUtility::trimExplode(',', strtoupper($tsfe->pSetup['insertClassesFromRTE.']['add_mainStyleOverrideDefs']), true);
517  foreach ($pageTSConfig['RTE.']['default.']['mainStyleOverride_add.'] as $mSOa_key => $mSOa_value) {
518  if (!is_array($mSOa_value) && (in_array('*', $mSOa_tList) || in_array($mSOa_key, $mSOa_tList))) {
519  $style .= '
520 ' . $mSOa_key . ' {' . $mSOa_value . '}';
521  }
522  }
523  }
524  }
525  // Setting body tag margins in CSS:
526  if (isset($tsfe->pSetup['bodyTagMargins']) && $tsfe->pSetup['bodyTagMargins.']['useCSS']) {
527  $margins = (int)$tsfe->pSetup['bodyTagMargins'];
528  $style .= '
529  BODY {margin: ' . $margins . 'px ' . $margins . 'px ' . $margins . 'px ' . $margins . 'px;}';
530  }
531  // CSS_inlineStyle from TS
532  $style .= trim($tsfe->pSetup['CSS_inlineStyle']);
533  $style .= $tsfe->cObj->cObjGet($tsfe->pSetup['cssInline.'], 'cssInline.');
534  if (trim($style)) {
535  self::addCssToPageRenderer($style, true, 'additionalTSFEInlineStyle');
536  }
537  // Javascript Libraries
538  if (is_array($tsfe->pSetup['javascriptLibs.'])) {
539  // Include jQuery into the page renderer
540  if (!empty($tsfe->pSetup['javascriptLibs.']['jQuery'])) {
541  $jQueryTS = $tsfe->pSetup['javascriptLibs.']['jQuery.'];
542  // Check if version / source is set, if not set variable to "NULL" to use the default of the page renderer
543  $version = isset($jQueryTS['version']) ? $jQueryTS['version'] : null;
544  $source = isset($jQueryTS['source']) ? $jQueryTS['source'] : null;
545  // When "noConflict" is not set or "1" enable the default jQuery noConflict mode, otherwise disable the namespace
546  if (!isset($jQueryTS['noConflict']) || !empty($jQueryTS['noConflict'])) {
547  // Set namespace to the "noConflict.namespace" value if "noConflict.namespace" has a value
548  if (!empty($jQueryTS['noConflict.']['namespace'])) {
549  $namespace = $jQueryTS['noConflict.']['namespace'];
550  } else {
552  }
553  } else {
555  }
556  $pageRenderer->loadJquery($version, $source, $namespace);
557  }
558  }
559  // JavaScript library files
560  if (is_array($tsfe->pSetup['includeJSLibs.'])) {
561  foreach ($tsfe->pSetup['includeJSLibs.'] as $key => $JSfile) {
562  if (!is_array($JSfile)) {
563  if (isset($tsfe->pSetup['includeJSLibs.'][$key . '.']['if.']) && !$tsfe->cObj->checkIf($tsfe->pSetup['includeJSLibs.'][$key . '.']['if.'])) {
564  continue;
565  }
566  $ss = $tsfe->pSetup['includeJSLibs.'][$key . '.']['external'] ? $JSfile : $tsfe->tmpl->getFileName($JSfile);
567  if ($ss) {
568  $jsFileConfig = &$tsfe->pSetup['includeJSLibs.'][$key . '.'];
569  $type = $jsFileConfig['type'];
570  if (!$type) {
571  $type = 'text/javascript';
572  }
573 
574  $pageRenderer->addJsLibrary(
575  $key,
576  $ss,
577  $type,
578  empty($jsFileConfig['disableCompression']),
579  (bool)$jsFileConfig['forceOnTop'],
580  $jsFileConfig['allWrap'],
581  (bool)$jsFileConfig['excludeFromConcatenation'],
582  $jsFileConfig['allWrap.']['splitChar'],
583  (bool)$jsFileConfig['async'],
584  $jsFileConfig['integrity']
585  );
586  unset($jsFileConfig);
587  }
588  }
589  }
590  }
591  if (is_array($tsfe->pSetup['includeJSFooterlibs.'])) {
592  foreach ($tsfe->pSetup['includeJSFooterlibs.'] as $key => $JSfile) {
593  if (!is_array($JSfile)) {
594  if (isset($tsfe->pSetup['includeJSFooterlibs.'][$key . '.']['if.']) && !$tsfe->cObj->checkIf($tsfe->pSetup['includeJSFooterlibs.'][$key . '.']['if.'])) {
595  continue;
596  }
597  $ss = $tsfe->pSetup['includeJSFooterlibs.'][$key . '.']['external'] ? $JSfile : $tsfe->tmpl->getFileName($JSfile);
598  if ($ss) {
599  $jsFileConfig = &$tsfe->pSetup['includeJSFooterlibs.'][$key . '.'];
600  $type = $jsFileConfig['type'];
601  if (!$type) {
602  $type = 'text/javascript';
603  }
604  $pageRenderer->addJsFooterLibrary(
605  $key,
606  $ss,
607  $type,
608  empty($jsFileConfig['disableCompression']),
609  (bool)$jsFileConfig['forceOnTop'],
610  $jsFileConfig['allWrap'],
611  (bool)$jsFileConfig['excludeFromConcatenation'],
612  $jsFileConfig['allWrap.']['splitChar'],
613  (bool)$jsFileConfig['async'],
614  $jsFileConfig['integrity']
615  );
616  unset($jsFileConfig);
617  }
618  }
619  }
620  }
621  // JavaScript files
622  if (is_array($tsfe->pSetup['includeJS.'])) {
623  foreach ($tsfe->pSetup['includeJS.'] as $key => $JSfile) {
624  if (!is_array($JSfile)) {
625  if (isset($tsfe->pSetup['includeJS.'][$key . '.']['if.']) && !$tsfe->cObj->checkIf($tsfe->pSetup['includeJS.'][$key . '.']['if.'])) {
626  continue;
627  }
628  $ss = $tsfe->pSetup['includeJS.'][$key . '.']['external'] ? $JSfile : $tsfe->tmpl->getFileName($JSfile);
629  if ($ss) {
630  $jsConfig = &$tsfe->pSetup['includeJS.'][$key . '.'];
631  $type = $jsConfig['type'];
632  if (!$type) {
633  $type = 'text/javascript';
634  }
635  $pageRenderer->addJsFile(
636  $ss,
637  $type,
638  empty($jsConfig['disableCompression']),
639  (bool)$jsConfig['forceOnTop'],
640  $jsConfig['allWrap'],
641  (bool)$jsConfig['excludeFromConcatenation'],
642  $jsConfig['allWrap.']['splitChar'],
643  (bool)$jsConfig['async'],
644  $jsConfig['integrity']
645  );
646  unset($jsConfig);
647  }
648  }
649  }
650  }
651  if (is_array($tsfe->pSetup['includeJSFooter.'])) {
652  foreach ($tsfe->pSetup['includeJSFooter.'] as $key => $JSfile) {
653  if (!is_array($JSfile)) {
654  if (isset($tsfe->pSetup['includeJSFooter.'][$key . '.']['if.']) && !$tsfe->cObj->checkIf($tsfe->pSetup['includeJSFooter.'][$key . '.']['if.'])) {
655  continue;
656  }
657  $ss = $tsfe->pSetup['includeJSFooter.'][$key . '.']['external'] ? $JSfile : $tsfe->tmpl->getFileName($JSfile);
658  if ($ss) {
659  $jsConfig = &$tsfe->pSetup['includeJSFooter.'][$key . '.'];
660  $type = $jsConfig['type'];
661  if (!$type) {
662  $type = 'text/javascript';
663  }
664  $pageRenderer->addJsFooterFile(
665  $ss,
666  $type,
667  empty($jsConfig['disableCompression']),
668  (bool)$jsConfig['forceOnTop'],
669  $jsConfig['allWrap'],
670  (bool)$jsConfig['excludeFromConcatenation'],
671  $jsConfig['allWrap.']['splitChar'],
672  (bool)$jsConfig['async'],
673  $jsConfig['integrity']
674  );
675  unset($jsConfig);
676  }
677  }
678  }
679  }
680  // Headerdata
681  if (is_array($tsfe->pSetup['headerData.'])) {
682  $pageRenderer->addHeaderData($tsfe->cObj->cObjGet($tsfe->pSetup['headerData.'], 'headerData.'));
683  }
684  // Footerdata
685  if (is_array($tsfe->pSetup['footerData.'])) {
686  $pageRenderer->addFooterData($tsfe->cObj->cObjGet($tsfe->pSetup['footerData.'], 'footerData.'));
687  }
688  static::generatePageTitle();
689 
690  $metaTagsHtml = static::generateMetaTagHtml(
691  isset($tsfe->pSetup['meta.']) ? $tsfe->pSetup['meta.'] : [],
692  $tsfe->xhtmlVersion,
693  $tsfe->cObj
694  );
695  foreach ($metaTagsHtml as $metaTag) {
696  $pageRenderer->addMetaTag($metaTag);
697  }
698 
699  unset($tsfe->additionalHeaderData['JSCode']);
700  if (is_array($tsfe->config['INTincScript'])) {
701  $tsfe->additionalHeaderData['JSCode'] = $tsfe->JSCode;
702  // Storing the JSCode vars...
703  $tsfe->config['INTincScript_ext']['divKey'] = $tsfe->uniqueHash();
704  $tsfe->config['INTincScript_ext']['additionalHeaderData'] = $tsfe->additionalHeaderData;
705  // Storing the header-data array
706  $tsfe->config['INTincScript_ext']['additionalFooterData'] = $tsfe->additionalFooterData;
707  // Storing the footer-data array
708  $tsfe->config['INTincScript_ext']['additionalJavaScript'] = $tsfe->additionalJavaScript;
709  // Storing the JS-data array
710  $tsfe->config['INTincScript_ext']['additionalCSS'] = $tsfe->additionalCSS;
711  // Storing the Style-data array
712  $tsfe->additionalHeaderData = ['<!--HD_' . $tsfe->config['INTincScript_ext']['divKey'] . '-->'];
713  // Clearing the array
714  $tsfe->additionalFooterData = ['<!--FD_' . $tsfe->config['INTincScript_ext']['divKey'] . '-->'];
715  // Clearing the array
716  $tsfe->divSection .= '<!--TDS_' . $tsfe->config['INTincScript_ext']['divKey'] . '-->';
717  } else {
718  $tsfe->INTincScript_loadJSCode();
719  }
720  $scriptJsCode = '';
721 
722  if ($tsfe->spamProtectEmailAddresses && $tsfe->spamProtectEmailAddresses !== 'ascii') {
723  $scriptJsCode = '
724  // decrypt helper function
725  function decryptCharcode(n,start,end,offset) {
726  n = n + offset;
727  if (offset > 0 && n > end) {
728  n = start + (n - end - 1);
729  } else if (offset < 0 && n < start) {
730  n = end - (start - n - 1);
731  }
732  return String.fromCharCode(n);
733  }
734  // decrypt string
735  function decryptString(enc,offset) {
736  var dec = "";
737  var len = enc.length;
738  for(var i=0; i < len; i++) {
739  var n = enc.charCodeAt(i);
740  if (n >= 0x2B && n <= 0x3A) {
741  dec += decryptCharcode(n,0x2B,0x3A,offset); // 0-9 . , - + / :
742  } else if (n >= 0x40 && n <= 0x5A) {
743  dec += decryptCharcode(n,0x40,0x5A,offset); // A-Z @
744  } else if (n >= 0x61 && n <= 0x7A) {
745  dec += decryptCharcode(n,0x61,0x7A,offset); // a-z
746  } else {
747  dec += enc.charAt(i);
748  }
749  }
750  return dec;
751  }
752  // decrypt spam-protected emails
753  function linkTo_UnCryptMailto(s) {
754  location.href = decryptString(s,' . $tsfe->spamProtectEmailAddresses * -1 . ');
755  }
756  ';
757  }
758  // Add inline JS
759  $inlineJS = '';
760  // defined in php
761  if (is_array($tsfe->inlineJS)) {
762  foreach ($tsfe->inlineJS as $key => $val) {
763  if (!is_array($val)) {
764  $inlineJS .= LF . $val . LF;
765  }
766  }
767  }
768  // defined in TS with page.inlineJS
769  // Javascript inline code
770  $inline = $tsfe->cObj->cObjGet($tsfe->pSetup['jsInline.'], 'jsInline.');
771  if ($inline) {
772  $inlineJS .= LF . $inline . LF;
773  }
774  // Javascript inline code for Footer
775  $inlineFooterJs = $tsfe->cObj->cObjGet($tsfe->pSetup['jsFooterInline.'], 'jsFooterInline.');
776  // Should minify?
777  if ($tsfe->config['config']['compressJs']) {
778  $pageRenderer->enableCompressJavascript();
779  $minifyErrorScript = ($minifyErrorInline = '');
780  $scriptJsCode = GeneralUtility::minifyJavaScript($scriptJsCode, $minifyErrorScript);
781  if ($minifyErrorScript) {
782  $timeTracker->setTSlogMessage($minifyErrorScript, 3);
783  }
784  if ($inlineJS) {
785  $inlineJS = GeneralUtility::minifyJavaScript($inlineJS, $minifyErrorInline);
786  if ($minifyErrorInline) {
787  $timeTracker->setTSlogMessage($minifyErrorInline, 3);
788  }
789  }
790  if ($inlineFooterJs) {
791  $inlineFooterJs = GeneralUtility::minifyJavaScript($inlineFooterJs, $minifyErrorInline);
792  if ($minifyErrorInline) {
793  $timeTracker->setTSlogMessage($minifyErrorInline, 3);
794  }
795  }
796  }
797  if (!$tsfe->config['config']['removeDefaultJS']) {
798  // include default and inlineJS
799  if ($scriptJsCode) {
800  $pageRenderer->addJsInlineCode('_scriptCode', $scriptJsCode, $tsfe->config['config']['compressJs']);
801  }
802  if ($inlineJS) {
803  $pageRenderer->addJsInlineCode('TS_inlineJS', $inlineJS, $tsfe->config['config']['compressJs']);
804  }
805  if ($inlineFooterJs) {
806  $pageRenderer->addJsFooterInlineCode('TS_inlineFooter', $inlineFooterJs, $tsfe->config['config']['compressJs']);
807  }
808  } elseif ($tsfe->config['config']['removeDefaultJS'] === 'external') {
809  /*
810  * This keeps inlineJS from *_INT Objects from being moved to external files.
811  * At this point in frontend rendering *_INT Objects only have placeholders instead
812  * of actual content so moving these placeholders to external files would
813  * a) break the JS file (syntax errors due to the placeholders)
814  * b) the needed JS would never get included to the page
815  * Therefore inlineJS from *_INT Objects must not be moved to external files but
816  * kept internal.
817  */
818  $inlineJSint = '';
819  self::stripIntObjectPlaceholder($inlineJS, $inlineJSint);
820  if ($inlineJSint) {
821  $pageRenderer->addJsInlineCode('TS_inlineJSint', $inlineJSint, $tsfe->config['config']['compressJs']);
822  }
823  if (trim($scriptJsCode . $inlineJS)) {
824  $pageRenderer->addJsFile(self::inline2TempFile($scriptJsCode . $inlineJS, 'js'), 'text/javascript', $tsfe->config['config']['compressJs']);
825  }
826  if ($inlineFooterJs) {
827  $inlineFooterJSint = '';
828  self::stripIntObjectPlaceholder($inlineFooterJs, $inlineFooterJSint);
829  if ($inlineFooterJSint) {
830  $pageRenderer->addJsFooterInlineCode('TS_inlineFooterJSint', $inlineFooterJSint, $tsfe->config['config']['compressJs']);
831  }
832  $pageRenderer->addJsFooterFile(self::inline2TempFile($inlineFooterJs, 'js'), 'text/javascript', $tsfe->config['config']['compressJs']);
833  }
834  } else {
835  // Include only inlineJS
836  if ($inlineJS) {
837  $pageRenderer->addJsInlineCode('TS_inlineJS', $inlineJS, $tsfe->config['config']['compressJs']);
838  }
839  if ($inlineFooterJs) {
840  $pageRenderer->addJsFooterInlineCode('TS_inlineFooter', $inlineFooterJs, $tsfe->config['config']['compressJs']);
841  }
842  }
843  if (is_array($tsfe->pSetup['inlineLanguageLabelFiles.'])) {
844  foreach ($tsfe->pSetup['inlineLanguageLabelFiles.'] as $key => $languageFile) {
845  if (is_array($languageFile)) {
846  continue;
847  }
848  $languageFileConfig = &$tsfe->pSetup['inlineLanguageLabelFiles.'][$key . '.'];
849  if (isset($languageFileConfig['if.']) && !$tsfe->cObj->checkIf($languageFileConfig['if.'])) {
850  continue;
851  }
852  $pageRenderer->addInlineLanguageLabelFile(
853  $languageFile,
854  $languageFileConfig['selectionPrefix'] ?: '',
855  $languageFileConfig['stripFromSelectionName'] ?: '',
856  $languageFileConfig['errorMode'] ? (int)$languageFileConfig['errorMode'] : 0
857  );
858  }
859  }
860  if (is_array($tsfe->pSetup['inlineSettings.'])) {
861  $pageRenderer->addInlineSettingArray('TS', $tsfe->pSetup['inlineSettings.']);
862  }
863  // Compression and concatenate settings
864  if ($tsfe->config['config']['compressCss']) {
865  $pageRenderer->enableCompressCss();
866  }
867  if ($tsfe->config['config']['compressJs']) {
868  $pageRenderer->enableCompressJavascript();
869  }
870  if ($tsfe->config['config']['concatenateCss']) {
871  $pageRenderer->enableConcatenateCss();
872  }
873  if ($tsfe->config['config']['concatenateJs']) {
874  $pageRenderer->enableConcatenateJavascript();
875  }
876  // Backward compatibility for old configuration
877  if ($tsfe->config['config']['concatenateJsAndCss']) {
878  $pageRenderer->enableConcatenateFiles();
879  }
880  // Add header data block
881  if ($tsfe->additionalHeaderData) {
882  $pageRenderer->addHeaderData(implode(LF, $tsfe->additionalHeaderData));
883  }
884  // Add footer data block
885  if ($tsfe->additionalFooterData) {
886  $pageRenderer->addFooterData(implode(LF, $tsfe->additionalFooterData));
887  }
888  // Header complete, now add content
889  if ($tsfe->pSetup['frameSet.']) {
891  'frameSet, FRAME and FRAMESET have been marked as deprecated since TYPO3 v8 ' .
892  'and will be removed in TYPO3 v9.'
893  );
894  $fs = GeneralUtility::makeInstance(FramesetRenderer::class);
895  $pageRenderer->addBodyContent($fs->make($tsfe->pSetup['frameSet.']));
896  $pageRenderer->addBodyContent(LF . '<noframes>' . LF);
897  }
898  // Bodytag:
899  if ($tsfe->config['config']['disableBodyTag']) {
900  $bodyTag = '';
901  } else {
902  $defBT = $tsfe->pSetup['bodyTagCObject'] ? $tsfe->cObj->cObjGetSingle($tsfe->pSetup['bodyTagCObject'], $tsfe->pSetup['bodyTagCObject.'], 'bodyTagCObject') : '<body>';
903  $bodyTag = $tsfe->pSetup['bodyTag'] ? $tsfe->pSetup['bodyTag'] : $defBT;
904  if (isset($tsfe->pSetup['bodyTagMargins'])) {
905  $margins = (int)$tsfe->pSetup['bodyTagMargins'];
906  if ($tsfe->pSetup['bodyTagMargins.']['useCSS']) {
907  } else {
908  $bodyTag = preg_replace('/>$/', '', trim($bodyTag)) . ' leftmargin="' . $margins . '" topmargin="' . $margins . '" marginwidth="' . $margins . '" marginheight="' . $margins . '">';
909  }
910  }
911  if (trim($tsfe->pSetup['bodyTagAdd'])) {
912  $bodyTag = preg_replace('/>$/', '', trim($bodyTag)) . ' ' . trim($tsfe->pSetup['bodyTagAdd']) . '>';
913  }
914  }
915  $pageRenderer->addBodyContent(LF . $bodyTag);
916  // Div-sections
917  if ($tsfe->divSection) {
918  $pageRenderer->addBodyContent(LF . $tsfe->divSection);
919  }
920  // Page content
921  $pageRenderer->addBodyContent(LF . $pageContent);
922  if (!empty($tsfe->config['INTincScript']) && is_array($tsfe->config['INTincScript'])) {
923  // Store the serialized pageRenderer in configuration
924  $tsfe->config['INTincScript_ext']['pageRenderer'] = serialize($pageRenderer);
925  // Render complete page, keep placeholders for JavaScript and CSS
926  $tsfe->content = $pageRenderer->renderPageWithUncachedObjects($tsfe->config['INTincScript_ext']['divKey']);
927  } else {
928  // Render complete page
929  $tsfe->content = $pageRenderer->render();
930  }
931  // Ending page
932  if ($tsfe->pSetup['frameSet.']) {
933  $tsfe->content .= LF . '</noframes>';
934  }
935  }
936 
937  /*************************
938  *
939  * Helper functions
940  * Remember: Calls internally must still be done on the non-instantiated class: PageGenerator::inline2TempFile()
941  *
942  *************************/
950  protected static function stripIntObjectPlaceholder(&$searchString, &$intObjects)
951  {
952  $tempArray = [];
953  preg_match_all('/\\<\\!--INT_SCRIPT.[a-z0-9]*--\\>/', $searchString, $tempArray);
954  $searchString = preg_replace('/\\<\\!--INT_SCRIPT.[a-z0-9]*--\\>/', '', $searchString);
955  $intObjects = implode('', $tempArray[0]);
956  }
957 
965  public static function inline2TempFile($str, $ext)
966  {
967  // Create filename / tags:
968  $script = '';
969  switch ($ext) {
970  case 'js':
971  $script = 'typo3temp/assets/js/' . GeneralUtility::shortMD5($str) . '.js';
972  break;
973  case 'css':
974  $script = 'typo3temp/assets/css/' . GeneralUtility::shortMD5($str) . '.css';
975  break;
976  }
977  // Write file:
978  if ($script) {
979  if (!@is_file(PATH_site . $script)) {
980  GeneralUtility::writeFileToTypo3tempDir(PATH_site . $script, $str);
981  }
982  }
983  return $script;
984  }
985 
993  public static function isAllowedLinkVarValue($haystack, $needle)
994  {
995  $OK = false;
996  // Integer
997  if ($needle === 'int' || $needle === 'integer') {
999  $OK = true;
1000  }
1001  } elseif (preg_match('/^\\/.+\\/[imsxeADSUXu]*$/', $needle)) {
1002  // Regular expression, only "//" is allowed as delimiter
1003  if (@preg_match($needle, $haystack)) {
1004  $OK = true;
1005  }
1006  } elseif (strstr($needle, '-')) {
1007  // Range
1008  if (MathUtility::canBeInterpretedAsInteger($haystack)) {
1009  $range = explode('-', $needle);
1010  if ($range[0] <= $haystack && $range[1] >= $haystack) {
1011  $OK = true;
1012  }
1013  }
1014  } elseif (strstr($needle, '|')) {
1015  // List
1016  // Trim the input
1017  $haystack = str_replace(' ', '', $haystack);
1018  if (strstr('|' . $needle . '|', '|' . $haystack . '|')) {
1019  $OK = true;
1020  }
1021  } elseif ((string)$needle === (string)$haystack) {
1022  // String comparison
1023  $OK = true;
1024  }
1025  return $OK;
1026  }
1027 
1034  public static function generatePageTitle()
1035  {
1037  $tsfe = $GLOBALS['TSFE'];
1038 
1039  $pageTitleSeparator = '';
1040 
1041  // check for a custom pageTitleSeparator, and perform stdWrap on it
1042  if (isset($tsfe->config['config']['pageTitleSeparator']) && $tsfe->config['config']['pageTitleSeparator'] !== '') {
1043  $pageTitleSeparator = $tsfe->config['config']['pageTitleSeparator'];
1044 
1045  if (isset($tsfe->config['config']['pageTitleSeparator.']) && is_array($tsfe->config['config']['pageTitleSeparator.'])) {
1046  $pageTitleSeparator = $tsfe->cObj->stdWrap($pageTitleSeparator, $tsfe->config['config']['pageTitleSeparator.']);
1047  } else {
1048  $pageTitleSeparator .= ' ';
1049  }
1050  }
1051 
1052  $titleTagContent = $tsfe->tmpl->printTitle(
1053  $tsfe->altPageTitle ?: $tsfe->page['title'],
1054  $tsfe->config['config']['noPageTitle'],
1055  $tsfe->config['config']['pageTitleFirst'],
1056  $pageTitleSeparator
1057  );
1058  if ($tsfe->config['config']['titleTagFunction']) {
1059  $titleTagContent = $tsfe->cObj->callUserFunction(
1060  $tsfe->config['config']['titleTagFunction'],
1061  [],
1062  $titleTagContent
1063  );
1064  }
1065  // stdWrap around the title tag
1066  if (isset($tsfe->config['config']['pageTitle.']) && is_array($tsfe->config['config']['pageTitle.'])) {
1067  $titleTagContent = $tsfe->cObj->stdWrap($titleTagContent, $tsfe->config['config']['pageTitle.']);
1068  }
1069  if ($titleTagContent !== '' && (int)$tsfe->config['config']['noPageTitle'] !== self::NO_PAGE_TITLE) {
1070  static::getPageRenderer()->setTitle($titleTagContent);
1071  }
1072  }
1073 
1082  protected static function generateMetaTagHtml(array $metaTagTypoScript, $xhtml, ContentObjectRenderer $cObj)
1083  {
1084  // Add ending slash only to documents rendered as xhtml
1085  $endingSlash = $xhtml ? ' /' : '';
1086 
1087  $metaTags = [
1088  '<meta name="generator" content="TYPO3 CMS"' . $endingSlash . '>'
1089  ];
1090 
1092  $typoScriptService = GeneralUtility::makeInstance(TypoScriptService::class);
1093  $conf = $typoScriptService->convertTypoScriptArrayToPlainArray($metaTagTypoScript);
1094  foreach ($conf as $key => $properties) {
1095  if (is_array($properties)) {
1096  $nodeValue = isset($properties['_typoScriptNodeValue']) ? $properties['_typoScriptNodeValue'] : '';
1097  $value = trim($cObj->stdWrap($nodeValue, $metaTagTypoScript[$key . '.']));
1098  if ($value === '' && !empty($properties['value'])) {
1099  $value = $properties['value'];
1100  }
1101  } else {
1102  $value = $properties;
1103  }
1104 
1105  $attribute = 'name';
1106  if ((is_array($properties) && !empty($properties['httpEquivalent'])) || strtolower($key) === 'refresh') {
1107  $attribute = 'http-equiv';
1108  }
1109  if (is_array($properties) && !empty($properties['attribute'])) {
1110  $attribute = $properties['attribute'];
1111  }
1112 
1113  if (!is_array($value)) {
1114  $value = (array)$value;
1115  }
1116  foreach ($value as $subValue) {
1117  if (trim($subValue) !== '') {
1118  $metaTags[] = '<meta ' . $attribute . '="' . $key . '" content="' . htmlspecialchars($subValue) . '"' . $endingSlash . '>';
1119  }
1120  }
1121  }
1122  return $metaTags;
1123  }
1124 
1132  protected static function initializeSearchWordDataInTsfe()
1133  {
1135  $tsfe = $GLOBALS['TSFE'];
1136 
1137  $tsfe->sWordRegEx = '';
1138  $tsfe->sWordList = GeneralUtility::_GP('sword_list');
1139  if (is_array($tsfe->sWordList)) {
1140  $space = !empty($tsfe->config['config']['sword_standAlone']) ? '[[:space:]]' : '';
1141  foreach ($tsfe->sWordList as $val) {
1142  if (trim($val) !== '') {
1143  $tsfe->sWordRegEx .= $space . preg_quote($val, '/') . $space . '|';
1144  }
1145  }
1146  $tsfe->sWordRegEx = rtrim($tsfe->sWordRegEx, '|');
1147  }
1148  }
1149 
1153  protected static function getPageRenderer()
1154  {
1155  return GeneralUtility::makeInstance(PageRenderer::class);
1156  }
1157 
1165  protected static function addCssToPageRenderer($cssStyles, $excludeFromConcatenation = false, $inlineBlockName = 'TSFEinlineStyle')
1166  {
1167  if (empty($GLOBALS['TSFE']->config['config']['inlineStyle2TempFile'])) {
1168  self::getPageRenderer()->addCssInlineBlock($inlineBlockName, $cssStyles, !empty($GLOBALS['TSFE']->config['config']['compressCss']));
1169  } else {
1170  self::getPageRenderer()->addCssFile(
1171  self::inline2TempFile($cssStyles, 'css'),
1172  'stylesheet',
1173  'all',
1174  '',
1175  (bool)$GLOBALS['TSFE']->config['config']['compressCss'],
1176  false,
1177  '',
1178  $excludeFromConcatenation
1179  );
1180  }
1181  }
1182 }
static minifyJavaScript($script, &$error='')
static intExplode($delimiter, $string, $removeEmptyValues=false, $limit=0)
static implodeAttributes(array $arr, $xhtmlSafe=false, $dontOmitBlankAttribs=false)
static isAllowedLinkVarValue($haystack, $needle)
static forceIntegerInRange($theInt, $min, $max=2000000000, $defaultValue=0)
Definition: MathUtility.php:31
static writeFileToTypo3tempDir($filepath, $content)
static getAbsoluteWebPath($targetPath)
Definition: PathUtility.php:40
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static stripIntObjectPlaceholder(&$searchString, &$intObjects)
static makeInstance($className,... $constructorArguments)
static addCssToPageRenderer($cssStyles, $excludeFromConcatenation=false, $inlineBlockName='TSFEinlineStyle')
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']