Fixed bugs #3655 and #4701: No wrappers for certain events (patch by Martin Kutschker)
[Packages/TYPO3.CMS.git] / typo3 / sysext / cms / tslib / class.tslib_pagegen.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2007 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Libraries for pagegen.php
29 * The script "pagegen.php" is included by "index_ts.php" when a page is not cached but needs to be rendered.
30 *
31 * $Id$
32 * Revised for TYPO3 3.6 June/2003 by Kasper Skaarhoj
33 * XHTML compliant
34 *
35 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
36 */
37 /**
38 * [CLASS/FUNCTION INDEX of SCRIPT]
39 *
40 *
41 *
42 * 88: class TSpagegen
43 * 95: function pagegenInit()
44 * 271: function getIncFiles()
45 * 304: function JSeventFunctions()
46 * 338: function renderContent()
47 * 365: function renderContentWithHeader($pageContent)
48 *
49 * SECTION: Helper functions
50 * 827: function inline2TempFile($str,$ext)
51 *
52 *
53 * 881: class FE_loadDBGroup extends t3lib_loadDBGroup
54 *
55 * TOTAL FUNCTIONS: 6
56 * (This index is automatically created/updated by the extension "extdeveval")
57 *
58 */
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78 /**
79 * Class for starting TypoScript page generation
80 *
81 * The class is not instantiated as an objects but called directly with the "::" operator.
82 * eg: TSpagegen::pagegenInit()
83 *
84 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
85 * @package TYPO3
86 * @subpackage tslib
87 */
88 class TSpagegen {
89
90 /**
91 * Setting some vars in TSFE, primarily based on TypoScript config settings.
92 *
93 * @return void
94 */
95 function pagegenInit() {
96 if ($GLOBALS['TSFE']->page['content_from_pid']>0) {
97 $temp_copy_TSFE = clone($GLOBALS['TSFE']); // make REAL copy of TSFE object - not reference!
98 $temp_copy_TSFE->id = $GLOBALS['TSFE']->page['content_from_pid']; // 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!
99 $temp_copy_TSFE->getPageAndRootlineWithDomain($GLOBALS['TSFE']->config['config']['content_from_pid_allowOutsideDomain']?0:$GLOBALS['TSFE']->domainStartPage);
100 $GLOBALS['TSFE']->contentPid = intval($temp_copy_TSFE->id);
101 unset($temp_copy_TSFE);
102 }
103 if ($GLOBALS['TSFE']->config['config']['MP_defaults']) {
104 $temp_parts = t3lib_div::trimExplode('|',$GLOBALS['TSFE']->config['config']['MP_defaults'],1);
105 reset($temp_parts);
106 while(list(,$temp_p)=each($temp_parts)) {
107 list($temp_idP,$temp_MPp) = explode(':',$temp_p,2);
108 $temp_ids=t3lib_div::intExplode(',',$temp_idP);
109 reset($temp_ids);
110 while(list(,$temp_id)=each($temp_ids)) {
111 $GLOBALS['TSFE']->MP_defaults[$temp_id]=$temp_MPp;
112 }
113 }
114 }
115 if ($GLOBALS['TSFE']->config['config']['simulateStaticDocuments_pEnc_onlyP']) {
116 $temp_parts = t3lib_div::trimExplode(',',$GLOBALS['TSFE']->config['config']['simulateStaticDocuments_pEnc_onlyP'],1);
117 foreach ($temp_parts as $temp_p) {
118 $GLOBALS['TSFE']->pEncAllowedParamNames[$temp_p]=1;
119 }
120 }
121
122
123 // Global vars...
124 $GLOBALS['TSFE']->indexedDocTitle = $GLOBALS['TSFE']->page['title'];
125 $GLOBALS['TSFE']->debug = ''.$GLOBALS['TSFE']->config['config']['debug'];
126
127 // Base url:
128 if ($GLOBALS['TSFE']->config['config']['baseURL']) {
129 if ($GLOBALS['TSFE']->config['config']['baseURL']==='1') {
130 // Deprecated property, going to be dropped.
131 $error = 'Unsupported TypoScript property was found in this template: "config.baseURL="1"
132
133 This setting has been deprecated in TYPO 3.8.1 due to security concerns.
134 You need to change this value to the URL of your website root, otherwise TYPO3 will not work!
135
136 See <a href="http://wiki.typo3.org/index.php/TYPO3_3.8.1" target="_blank">wiki.typo3.org/index.php/TYPO3_3.8.1</a> for more information.';
137
138 $GLOBALS['TSFE']->printError(nl2br($error));
139 exit;
140 } else {
141 $GLOBALS['TSFE']->baseUrl = $GLOBALS['TSFE']->config['config']['baseURL'];
142 }
143 $GLOBALS['TSFE']->anchorPrefix = substr(t3lib_div::getIndpEnv('TYPO3_REQUEST_URL'),strlen(t3lib_div::getIndpEnv('TYPO3_SITE_URL')));
144 }
145
146 // Internal and External target defaults
147 $GLOBALS['TSFE']->intTarget = ''.$GLOBALS['TSFE']->config['config']['intTarget'];
148 $GLOBALS['TSFE']->extTarget = ''.$GLOBALS['TSFE']->config['config']['extTarget'];
149 if ($GLOBALS['TSFE']->config['config']['spamProtectEmailAddresses'] === 'ascii') {
150 $GLOBALS['TSFE']->spamProtectEmailAddresses = 'ascii';
151 } else {
152 $GLOBALS['TSFE']->spamProtectEmailAddresses = t3lib_div::intInRange($GLOBALS['TSFE']->config['config']['spamProtectEmailAddresses'],-10,10,0);
153 }
154
155
156 $GLOBALS['TSFE']->absRefPrefix = trim(''.$GLOBALS['TSFE']->config['config']['absRefPrefix']);
157 if ((!strcmp($GLOBALS['TSFE']->config['config']['simulateStaticDocuments'],'PATH_INFO') || $GLOBALS['TSFE']->absRefPrefix_force)
158 && !$GLOBALS['TSFE']->absRefPrefix) {
159 $GLOBALS['TSFE']->absRefPrefix=t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/';
160 } // Force absRefPrefix to this value is PATH_INFO is used.
161
162 if ($GLOBALS['TSFE']->type && $GLOBALS['TSFE']->config['config']['frameReloadIfNotInFrameset']) {
163 $tdlLD = $GLOBALS['TSFE']->tmpl->linkData($GLOBALS['TSFE']->page,'_top',$GLOBALS['TSFE']->no_cache,'');
164 $GLOBALS['TSFE']->JSCode = 'if(!parent.'.trim($GLOBALS['TSFE']->sPre).' && !parent.view_frame) top.location.href="'.$GLOBALS['TSFE']->baseUrlWrap($tdlLD['totalURL']).'"';
165 }
166 $GLOBALS['TSFE']->compensateFieldWidth = ''.$GLOBALS['TSFE']->config['config']['compensateFieldWidth'];
167 $GLOBALS['TSFE']->lockFilePath = ''.$GLOBALS['TSFE']->config['config']['lockFilePath'];
168 $GLOBALS['TSFE']->lockFilePath = $GLOBALS['TSFE']->lockFilePath ? $GLOBALS['TSFE']->lockFilePath : 'fileadmin/';
169 $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'];
170 $GLOBALS['TSFE']->TYPO3_CONF_VARS['GFX']['im_noScaleUp'] = $GLOBALS['TYPO3_CONF_VARS']['GFX']['im_noScaleUp'];
171
172 $GLOBALS['TSFE']->ATagParams = trim($GLOBALS['TSFE']->config['config']['ATagParams']) ? ' '.trim($GLOBALS['TSFE']->config['config']['ATagParams']) : '';
173 if ($GLOBALS['TSFE']->config['config']['setJS_mouseOver']) $GLOBALS['TSFE']->setJS('mouseOver');
174 if ($GLOBALS['TSFE']->config['config']['setJS_openPic']) $GLOBALS['TSFE']->setJS('openPic');
175
176 $GLOBALS['TSFE']->sWordRegEx='';
177 $GLOBALS['TSFE']->sWordList = t3lib_div::_GP('sword_list');
178 if (is_array($GLOBALS['TSFE']->sWordList)) {
179 $standAlone = trim(''.$GLOBALS['TSFE']->config['config']['sword_standAlone']);
180 $noMixedCase = trim(''.$GLOBALS['TSFE']->config['config']['sword_noMixedCase']);
181
182 $space = ($standAlone) ? '[[:space:]]' : '';
183 reset($GLOBALS['TSFE']->sWordList);
184 while (list($key,$val) = each($GLOBALS['TSFE']->sWordList)) {
185 if (trim($val)) {
186 if (!$noMixedCase) {
187 $GLOBALS['TSFE']->sWordRegEx.= $space.sql_regcase(quotemeta($val)).$space.'|';
188 } else {
189 $GLOBALS['TSFE']->sWordRegEx.= $space.quotemeta($val).$space.'|';
190 }
191 }
192 }
193 $GLOBALS['TSFE']->sWordRegEx = ereg_replace('\|$','',$GLOBALS['TSFE']->sWordRegEx);
194 }
195
196 // linkVars
197 $linkVars = (string)$GLOBALS['TSFE']->config['config']['linkVars'];
198 if ($linkVars) {
199 $linkVarArr = explode(',',$linkVars);
200
201 $GLOBALS['TSFE']->linkVars='';
202 $GET = t3lib_div::_GET();
203
204 foreach ($linkVarArr as $val) {
205 $val = trim($val);
206
207 if (preg_match('/^(.*)\((.+)\)$/',$val,$match)) {
208 $val = trim($match[1]);
209 $test = trim($match[2]);
210 } else unset($test);
211
212 if ($val && isset($GET[$val])) {
213 if (!is_array($GET[$val])) {
214 $tmpVal = rawurlencode($GET[$val]);
215
216 if ($test && !TSpagegen::isAllowedLinkVarValue($tmpVal,$test)) {
217 continue; // Error: This value was not allowed for this key
218 }
219
220 $value = '&'.$val.'='.$tmpVal;
221 } else {
222 if ($test && strcmp('array',$test)) {
223 continue; // Error: This key must not be an array!
224 }
225 $value = t3lib_div::implodeArrayForUrl($val,$GET[$val]);
226 }
227 } else continue;
228
229 $GLOBALS['TSFE']->linkVars.= $value;
230 }
231 unset($GET);
232 } else {
233 $GLOBALS['TSFE']->linkVars='';
234 }
235
236 // Setting XHTML-doctype from doctype
237 if (!$GLOBALS['TSFE']->config['config']['xhtmlDoctype']) {
238 $GLOBALS['TSFE']->config['config']['xhtmlDoctype'] = $GLOBALS['TSFE']->config['config']['doctype'];
239 }
240
241 if ($GLOBALS['TSFE']->config['config']['xhtmlDoctype']) {
242 $GLOBALS['TSFE']->xhtmlDoctype = $GLOBALS['TSFE']->config['config']['xhtmlDoctype'];
243
244 // Checking XHTML-docytpe
245 switch((string)$GLOBALS['TSFE']->config['config']['xhtmlDoctype']) {
246 case 'xhtml_trans':
247 case 'xhtml_strict':
248 case 'xhtml_frames':
249 $GLOBALS['TSFE']->xhtmlVersion = 100;
250 break;
251 case 'xhtml_basic':
252 $GLOBALS['TSFE']->xhtmlVersion = 105;
253 break;
254 case 'xhtml_11':
255 $GLOBALS['TSFE']->xhtmlVersion = 110;
256 break;
257 case 'xhtml_2':
258 $GLOBALS['TSFE']->xhtmlVersion = 200;
259 break;
260 default:
261 $GLOBALS['TSFE']->xhtmlDoctype = '';
262 $GLOBALS['TSFE']->xhtmlVersion = 0;
263 }
264 }
265 }
266
267 /**
268 * Returns an array with files to include. These files are the ones set up in TypoScript config.
269 *
270 * @return array Files to include. Paths are relative to PATH_site.
271 */
272 function getIncFiles() {
273 $incFilesArray = array();
274 // Get files from config.includeLibrary
275 $includeLibrary = trim(''.$GLOBALS['TSFE']->config['config']['includeLibrary']);
276 if ($includeLibrary) {
277 $incFile=$GLOBALS['TSFE']->tmpl->getFileName($includeLibrary);
278 if ($incFile) {
279 $incFilesArray[] = $incFile;
280 }
281 }
282
283 if (is_array($GLOBALS['TSFE']->pSetup['includeLibs.'])) {$incLibs=$GLOBALS['TSFE']->pSetup['includeLibs.'];} else {$incLibs=array();}
284 if (is_array($GLOBALS['TSFE']->tmpl->setup['includeLibs.'])) {$incLibs+=$GLOBALS['TSFE']->tmpl->setup['includeLibs.'];} // 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)
285 if (count($incLibs)) {
286 reset($incLibs);
287 while(list(,$theLib)=each($incLibs)) {
288 if (!is_array($theLib) && $incFile=$GLOBALS['TSFE']->tmpl->getFileName($theLib)) {
289 $incFilesArray[] = $incFile;
290 }
291 }
292 }
293 // Include HTML mail library?
294 if ($GLOBALS['TSFE']->config['config']['incT3Lib_htmlmail']) {
295 $incFilesArray[] = 't3lib/class.t3lib_htmlmail.php';
296 }
297 return $incFilesArray;
298 }
299
300 /**
301 * Processing JavaScript handlers
302 *
303 * @return array Array with a) a JavaScript section with event handlers and variables set and b) an array with attributes for the body tag.
304 */
305 function JSeventFunctions() {
306 $functions = array();
307 $setEvents = array();
308 $setBody = array();
309
310 foreach ($GLOBALS['TSFE']->JSeventFuncCalls as $event => $handlers) {
311 if (count($handlers)) {
312 $functions[] = ' function T3_'.$event.'Wrapper(e) { '.implode(' ',$handlers).' }';
313 $setEvents[] = ' document.'.$event.'=T3_'.$event.'Wrapper;';
314 if ($event == 'onload') {
315 $setBody[]='onload="T3_onloadWrapper();"'; // dubiuos double setting breaks on some browser - do we need it?
316 }
317 }
318 }
319
320 return Array(count($functions)?'
321 <script type="text/javascript">
322 /*<![CDATA[*/
323 '.implode(chr(10),$functions).'
324 '.implode(chr(10),$setEvents).'
325 /*]]>*/
326 </script>
327 ':'',$setBody);
328 }
329
330 /**
331 * Rendering the page content
332 *
333 * @return void
334 */
335 function renderContent() {
336 // PAGE CONTENT
337 $GLOBALS['TT']->incStackPointer();
338 $GLOBALS['TT']->push($GLOBALS['TSFE']->sPre, 'PAGE');
339 $pageContent = $GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup);
340
341 if ($GLOBALS['TSFE']->pSetup['wrap']) {$pageContent = $GLOBALS['TSFE']->cObj->wrap($pageContent, $GLOBALS['TSFE']->pSetup['wrap']);}
342 if ($GLOBALS['TSFE']->pSetup['stdWrap.']) {$pageContent = $GLOBALS['TSFE']->cObj->stdWrap($pageContent, $GLOBALS['TSFE']->pSetup['stdWrap.']);}
343
344 // PAGE HEADER (after content - maybe JS is inserted!
345
346 // if 'disableAllHeaderCode' is set, all the header-code is discarded!
347 if ($GLOBALS['TSFE']->config['config']['disableAllHeaderCode']) {
348 $GLOBALS['TSFE']->content = $pageContent;
349 } else {
350 TSpagegen::renderContentWithHeader($pageContent);
351 }
352 $GLOBALS['TT']->pull($GLOBALS['TT']->LR?$GLOBALS['TSFE']->content:'');
353 $GLOBALS['TT']->decStackPointer();
354 }
355
356 /**
357 * Rendering normal HTML-page with header by wrapping the generated content ($pageContent) in body-tags and setting the header accordingly.
358 *
359 * @param string The page content which TypoScript objects has generated
360 * @return void
361 */
362 function renderContentWithHeader($pageContent) {
363 $customContent = $GLOBALS['TSFE']->config['config']['headerComment'];
364 if (trim($customContent)) {
365 $customContent = chr(10).$customContent;
366 } else $customContent='';
367
368 // Setting charset:
369 $theCharset = $GLOBALS['TSFE']->metaCharset;
370
371 // Reset the content variables:
372 $GLOBALS['TSFE']->content='';
373 $htmlTagAttributes = array();
374 $htmlLang = $GLOBALS['TSFE']->config['config']['htmlTag_langKey'] ? $GLOBALS['TSFE']->config['config']['htmlTag_langKey'] : 'en';
375
376 // Set content direction: (More info: http://www.tau.ac.il/~danon/Hebrew/HTML_and_Hebrew.html)
377 if ($GLOBALS['TSFE']->config['config']['htmlTag_dir']) {
378 $htmlTagAttributes['dir'] = htmlspecialchars($GLOBALS['TSFE']->config['config']['htmlTag_dir']);
379 }
380
381 // Setting document type:
382 $docTypeParts = array();
383 // Part 1: XML prologue
384 switch((string)$GLOBALS['TSFE']->config['config']['xmlprologue']) {
385 case 'none':
386 break;
387 case 'xml_10':
388 $docTypeParts[]='<?xml version="1.0" encoding="'.$theCharset.'"?>';
389 break;
390 case 'xml_11':
391 $docTypeParts[]='<?xml version="1.1" encoding="'.$theCharset.'"?>';
392 break;
393 case '':
394 if ($GLOBALS['TSFE']->xhtmlVersion) $docTypeParts[]='<?xml version="1.0" encoding="'.$theCharset.'"?>';
395 break;
396 default:
397 $docTypeParts[]=$GLOBALS['TSFE']->config['config']['xmlprologue'];
398 }
399 // Part 2: DTD
400 if ($GLOBALS['TSFE']->config['config']['doctype']) {
401 switch((string)$GLOBALS['TSFE']->config['config']['doctype']) {
402 case 'xhtml_trans':
403 $docTypeParts[]='<!DOCTYPE html
404 PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
405 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
406 break;
407 case 'xhtml_strict':
408 $docTypeParts[]='<!DOCTYPE html
409 PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
410 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
411 break;
412 case 'xhtml_frames':
413 $docTypeParts[]='<!DOCTYPE html
414 PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN"
415 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
416 break;
417 case 'xhtml_basic':
418 $docTypeParts[]='<!DOCTYPE html
419 PUBLIC "-//W3C//DTD XHTML Basic 1.0//EN"
420 "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd">';
421 break;
422 case 'xhtml_11':
423 $docTypeParts[]='<!DOCTYPE html
424 PUBLIC "-//W3C//DTD XHTML 1.1//EN"
425 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
426 break;
427 case 'xhtml_2':
428 $docTypeParts[]='<!DOCTYPE html
429 PUBLIC "-//W3C//DTD XHTML 2.0//EN"
430 "http://www.w3.org/TR/xhtml2/DTD/xhtml2.dtd">';
431 break;
432 case 'none':
433 break;
434 default:
435 $docTypeParts[] = $GLOBALS['TSFE']->config['config']['doctype'];
436 }
437 } else {
438 $docTypeParts[]='<!DOCTYPE html
439 PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
440 }
441
442 if ($GLOBALS['TSFE']->xhtmlVersion) {
443
444 // Setting <html> tag attributes:
445 $htmlTagAttributes['xmlns'] = 'http://www.w3.org/1999/xhtml';
446 $htmlTagAttributes['xml:lang'] = $htmlLang;
447 if ($GLOBALS['TSFE']->xhtmlVersion < 110) {
448 $htmlTagAttributes['lang'] = $htmlLang;
449 }
450 }
451
452 // Swap XML and doctype order around (for MSIE / Opera standards compliance)
453 if ($GLOBALS['TSFE']->config['config']['doctypeSwitch']) {
454 $docTypeParts = array_reverse($docTypeParts);
455 }
456
457 // Adding doctype parts:
458 $GLOBALS['TSFE']->content.= count($docTypeParts) ? implode(chr(10),$docTypeParts).chr(10) : '';
459
460 // Begin header section:
461 if (strcmp($GLOBALS['TSFE']->config['config']['htmlTag_setParams'],'none')) {
462 $_attr = $GLOBALS['TSFE']->config['config']['htmlTag_setParams'] ? $GLOBALS['TSFE']->config['config']['htmlTag_setParams'] : t3lib_div::implodeAttributes($htmlTagAttributes);
463 } else {
464 $_attr = '';
465 }
466 $GLOBALS['TSFE']->content.='<html'.($_attr ? ' '.$_attr : '').'>';
467
468 // Head tag:
469 $headTag = $GLOBALS['TSFE']->pSetup['headTag'] ? $GLOBALS['TSFE']->pSetup['headTag'] : '<head>';
470 $GLOBALS['TSFE']->content.= chr(10).$headTag;
471
472 // Setting charset meta tag:
473 $GLOBALS['TSFE']->content.='
474 <meta http-equiv="Content-Type" content="text/html; charset='.$theCharset.'" />';
475
476 $GLOBALS['TSFE']->content.='
477
478 <!-- '.($customContent?$customContent.chr(10):'').'
479 This website is powered by TYPO3 - inspiring people to share!
480 TYPO3 is a free open source Content Management Framework initially created by Kasper Skaarhoj and licensed under GNU/GPL.
481 TYPO3 is copyright 1998-2006 of Kasper Skaarhoj. Extensions are copyright of their respective owners.
482 Information and contribution at http://typo3.com/ and http://typo3.org/
483 -->
484 ';
485
486
487 if ($GLOBALS['TSFE']->baseUrl) {
488 $GLOBALS['TSFE']->content.='
489 <base href="'.htmlspecialchars($GLOBALS['TSFE']->baseUrl).'" />';
490 }
491
492 if ($GLOBALS['TSFE']->pSetup['shortcutIcon']) {
493 $ss=$path.$GLOBALS['TSFE']->tmpl->getFileName($GLOBALS['TSFE']->pSetup['shortcutIcon']);
494 $GLOBALS['TSFE']->content.='
495 <link rel="SHORTCUT ICON" href="'.htmlspecialchars($ss).'" />';
496 }
497
498 // Including CSS files
499 if (is_array($GLOBALS['TSFE']->tmpl->setup['plugin.'])) {
500 $temp_styleLines=array();
501 foreach ($GLOBALS['TSFE']->tmpl->setup['plugin.'] as $key=>$iCSScode) {
502 if (is_array($iCSScode) && $iCSScode['_CSS_DEFAULT_STYLE']) {
503 $temp_styleLines[]='/* default styles for extension "'.substr($key,0,-1).'" */'.chr(10).$iCSScode['_CSS_DEFAULT_STYLE'];
504 }
505 }
506 if (count($temp_styleLines)) {
507 if ($GLOBALS['TSFE']->config['config']['inlineStyle2TempFile']) {
508 $GLOBALS['TSFE']->content.=TSpagegen::inline2TempFile(implode(chr(10),$temp_styleLines),'css');
509 } else {
510 $GLOBALS['TSFE']->content.='
511 <style type="text/css">
512 /*<![CDATA[*/
513 <!--
514 '.implode(chr(10),$temp_styleLines).'
515 -->
516 /*]]>*/
517 </style>';
518 }
519 }
520 }
521
522 if ($GLOBALS['TSFE']->pSetup['stylesheet']) {
523 $ss=$GLOBALS['TSFE']->tmpl->getFileName($GLOBALS['TSFE']->pSetup['stylesheet']);
524 if ($ss) {
525 $GLOBALS['TSFE']->content.='
526 <link rel="stylesheet" type="text/css" href="'.htmlspecialchars($ss).'" />';
527 }
528 }
529 if (is_array($GLOBALS['TSFE']->pSetup['includeCSS.'])) {
530 foreach ($GLOBALS['TSFE']->pSetup['includeCSS.'] as $key=>$iCSSfile) {
531 if (!is_array($iCSSfile)) {
532 $ss=$GLOBALS['TSFE']->tmpl->getFileName($iCSSfile);
533 if ($ss) {
534 if ($GLOBALS['TSFE']->pSetup['includeCSS.'][$key.'.']['import']) {
535 if (substr($ss,0,1)!='/') { // To fix MSIE 6 that cannot handle these as relative paths (according to Ben v Ende)
536 $ss = t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')).'/'.$ss;
537 }
538 $GLOBALS['TSFE']->content.='
539 <style type="text/css">
540 <!--
541 @import url("'.htmlspecialchars($ss).'") '.htmlspecialchars($GLOBALS['TSFE']->pSetup['includeCSS.'][$key.'.']['media']).';
542 -->
543 </style>
544 ';
545 } else {
546 $GLOBALS['TSFE']->content.='
547 <link rel="'.($GLOBALS['TSFE']->pSetup['includeCSS.'][$key.'.']['alternate'] ? 'alternate stylesheet' : 'stylesheet').'" type="text/css" href="'.htmlspecialchars($ss).'"'.
548 ($GLOBALS['TSFE']->pSetup['includeCSS.'][$key.'.']['title'] ? ' title="'.htmlspecialchars($GLOBALS['TSFE']->pSetup['includeCSS.'][$key.'.']['title']).'"' : '').
549 ($GLOBALS['TSFE']->pSetup['includeCSS.'][$key.'.']['media'] ? ' media="'.htmlspecialchars($GLOBALS['TSFE']->pSetup['includeCSS.'][$key.'.']['media']).'"' : '').
550 ' />';
551 }
552 }
553 }
554 }
555 }
556
557 // Stylesheets
558 $style='';
559 $style.=trim($GLOBALS['TSFE']->pSetup['CSS_inlineStyle']).chr(10);
560
561 if ($GLOBALS['TSFE']->pSetup['insertClassesFromRTE']) {
562 $pageTSConfig = $GLOBALS['TSFE']->getPagesTSconfig();
563 $RTEclasses = $pageTSConfig['RTE.']['classes.'];
564 if (is_array($RTEclasses)) {
565 foreach ($RTEclasses as $RTEclassName=>$RTEvalueArray) {
566 if ($RTEvalueArray['value']) {
567 $style.='
568 .'.substr($RTEclassName,0,-1).' {'.$RTEvalueArray['value'].'}';
569 }
570 }
571 }
572
573 if ($GLOBALS['TSFE']->pSetup['insertClassesFromRTE.']['add_mainStyleOverrideDefs'] && is_array($pageTSConfig['RTE.']['default.']['mainStyleOverride_add.'])) {
574 $mSOa_tList = t3lib_div::trimExplode(',',strtoupper($GLOBALS['TSFE']->pSetup['insertClassesFromRTE.']['add_mainStyleOverrideDefs']),1);
575 foreach ($pageTSConfig['RTE.']['default.']['mainStyleOverride_add.'] as $mSOa_key=>$mSOa_value) {
576 if (!is_array($mSOa_value) && (in_array('*',$mSOa_tList)||in_array($mSOa_key,$mSOa_tList))) {
577 $style.='
578 '.$mSOa_key.' {'.$mSOa_value.'}';
579 }
580 }
581 }
582 }
583
584 // Setting body tag margins in CSS:
585 if (isset($GLOBALS['TSFE']->pSetup['bodyTagMargins']) && $GLOBALS['TSFE']->pSetup['bodyTagMargins.']['useCSS']) {
586 $margins = intval($GLOBALS['TSFE']->pSetup['bodyTagMargins']);
587 $style.='
588 BODY {margin: '.$margins.'px '.$margins.'px '.$margins.'px '.$margins.'px;}';
589 }
590
591 if ($GLOBALS['TSFE']->pSetup['noLinkUnderline']) {
592 $style.='
593 A:link {text-decoration: none}
594 A:visited {text-decoration: none}
595 A:active {text-decoration: none}';
596 }
597 if (trim($GLOBALS['TSFE']->pSetup['hover'])) {
598 $style.='
599 A:hover {color: '.trim($GLOBALS['TSFE']->pSetup['hover']).';}';
600 }
601 if (trim($GLOBALS['TSFE']->pSetup['hoverStyle'])) {
602 $style.='
603 A:hover {'.trim($GLOBALS['TSFE']->pSetup['hoverStyle']).'}';
604 }
605 if ($GLOBALS['TSFE']->pSetup['smallFormFields']) {
606 $style.='
607 SELECT { font-family: Verdana, Arial, Helvetica; font-size: 10px }
608 TEXTAREA { font-family: Verdana, Arial, Helvetica; font-size: 10px}
609 INPUT { font-family: Verdana, Arial, Helvetica; font-size: 10px }';
610 }
611 if ($GLOBALS['TSFE']->pSetup['adminPanelStyles']) {
612 $style.='
613
614 /* Default styles for the Admin Panel */
615 TABLE.typo3-adminPanel { border: 1px solid black; background-color: #F6F2E6; }
616 TABLE.typo3-adminPanel TR.typo3-adminPanel-hRow TD { background-color: #9BA1A8; }
617 TABLE.typo3-adminPanel TR.typo3-adminPanel-itemHRow TD { background-color: #ABBBB4; }
618 TABLE.typo3-adminPanel TABLE, TABLE.typo3-adminPanel TD { border: 0px; }
619 TABLE.typo3-adminPanel TD FONT { font-family: verdana; font-size: 10px; color: black; }
620 TABLE.typo3-adminPanel TD A FONT { font-family: verdana; font-size: 10px; color: black; }
621 TABLE.typo3-editPanel { border: 1px solid black; background-color: #F6F2E6; }
622 TABLE.typo3-editPanel TD { border: 0px; }
623 ';
624 }
625
626 if (trim($style)) {
627 if ($GLOBALS['TSFE']->config['config']['inlineStyle2TempFile']) {
628 $GLOBALS['TSFE']->content.=TSpagegen::inline2TempFile($style, 'css');
629 } else {
630 $GLOBALS['TSFE']->content.='
631 <style type="text/css">
632 /*<![CDATA[*/
633 <!--'.$style.'
634 -->
635 /*]]>*/
636 </style>';
637 }
638 }
639
640 // JavaScript files
641 if (is_array($GLOBALS['TSFE']->pSetup['includeJS.'])) {
642 foreach ($GLOBALS['TSFE']->pSetup['includeJS.'] as $key=>$JSfile) {
643 if (!is_array($JSfile)) {
644 $ss = $GLOBALS['TSFE']->tmpl->getFileName($JSfile);
645 if ($ss) {
646 $type = $GLOBALS['TSFE']->pSetup['includeJS.'][$key.'.']['type'];
647 if (!$type) $type = 'text/javascript';
648
649 $GLOBALS['TSFE']->content.='
650 <script src="'.htmlspecialchars($ss).'" type="'.htmlspecialchars($type).'"></script>';
651 }
652 }
653 }
654 }
655
656
657
658
659
660 // Headerdata
661 if (is_array($GLOBALS['TSFE']->pSetup['headerData.'])) {
662 $GLOBALS['TSFE']->content.= chr(10).$GLOBALS['TSFE']->cObj->cObjGet($GLOBALS['TSFE']->pSetup['headerData.'],'headerData.');
663 }
664
665 // Title
666 $titleTagContent = $GLOBALS['TSFE']->tmpl->printTitle(
667 $GLOBALS['TSFE']->altPageTitle?$GLOBALS['TSFE']->altPageTitle:$GLOBALS['TSFE']->page['title'],
668 $GLOBALS['TSFE']->config['config']['noPageTitle'],
669 $GLOBALS['TSFE']->config['config']['pageTitleFirst']
670 );
671 if ($GLOBALS['TSFE']->config['config']['titleTagFunction']) {
672 $titleTagContent = $GLOBALS['TSFE']->cObj->callUserFunction($GLOBALS['TSFE']->config['config']['titleTagFunction'], array(), $titleTagContent);
673 }
674
675 if (strlen($titleTagContent) && intval($GLOBALS['TSFE']->config['config']['noPageTitle'])!==2) {
676 $GLOBALS['TSFE']->content.='
677 <title>'.htmlspecialchars($titleTagContent).'</title>';
678 }
679 $GLOBALS['TSFE']->content.='
680 <meta name="generator" content="TYPO3 '.TYPO3_branch.' CMS" />';
681
682 $conf=$GLOBALS['TSFE']->pSetup['meta.'];
683 if (is_array($conf)) {
684 reset($conf);
685 while(list($theKey,$theValue)=each($conf)) {
686 if (!strstr($theKey,'.') || !isset($conf[substr($theKey,0,-1)])) { // Only if 1) the property is set but not the value itself, 2) the value and/or any property
687 if (strstr($theKey,'.')) {
688 $theKey = substr($theKey,0,-1);
689 }
690 $val = $GLOBALS['TSFE']->cObj->stdWrap($conf[$theKey],$conf[$theKey.'.']);
691 $key = $theKey;
692 if (trim($val)) {
693 $a='name';
694 if (strtolower($key)=='refresh') {$a='http-equiv';}
695 $GLOBALS['TSFE']->content.= '
696 <meta '.$a.'="'.$key.'" content="'.htmlspecialchars(trim($val)).'" />';
697 }
698 }
699 }
700 }
701
702 unset($GLOBALS['TSFE']->additionalHeaderData['JSCode']);
703 unset($GLOBALS['TSFE']->additionalHeaderData['JSImgCode']);
704
705 if (is_array($GLOBALS['TSFE']->config['INTincScript'])) {
706 // Storing the JSCode and JSImgCode vars...
707 $GLOBALS['TSFE']->additionalHeaderData['JSCode'] = $GLOBALS['TSFE']->JSCode;
708 $GLOBALS['TSFE']->additionalHeaderData['JSImgCode'] = $GLOBALS['TSFE']->JSImgCode;
709 $GLOBALS['TSFE']->config['INTincScript_ext']['divKey'] = $GLOBALS['TSFE']->uniqueHash();
710 $GLOBALS['TSFE']->config['INTincScript_ext']['additionalHeaderData'] = $GLOBALS['TSFE']->additionalHeaderData; // Storing the header-data array
711 $GLOBALS['TSFE']->config['INTincScript_ext']['additionalJavaScript'] = $GLOBALS['TSFE']->additionalJavaScript; // Storing the JS-data array
712 $GLOBALS['TSFE']->config['INTincScript_ext']['additionalCSS'] = $GLOBALS['TSFE']->additionalCSS; // Storing the Style-data array
713
714 $GLOBALS['TSFE']->additionalHeaderData = array('<!--HD_'.$GLOBALS['TSFE']->config['INTincScript_ext']['divKey'].'-->'); // Clearing the array
715 $GLOBALS['TSFE']->divSection.= '<!--TDS_'.$GLOBALS['TSFE']->config['INTincScript_ext']['divKey'].'-->';
716 } else {
717 $GLOBALS['TSFE']->INTincScript_loadJSCode();
718 }
719 $JSef = TSpagegen::JSeventFunctions();
720
721 // Adding default Java Script:
722 $_scriptCode = '
723 var browserName = navigator.appName;
724 var browserVer = parseInt(navigator.appVersion);
725 var version = "";
726 var msie4 = (browserName == "Microsoft Internet Explorer" && browserVer >= 4);
727 if ((browserName == "Netscape" && browserVer >= 3) || msie4 || browserName=="Konqueror" || browserName=="Opera") {version = "n3";} else {version = "n2";}
728 // Blurring links:
729 function blurLink(theObject) { //
730 if (msie4) {theObject.blur();}
731 }
732 ';
733
734 if ($GLOBALS['TSFE']->spamProtectEmailAddresses && $GLOBALS['TSFE']->spamProtectEmailAddresses !== 'ascii') {
735 $_scriptCode.= '
736 // decrypt helper function
737 function decryptCharcode(n,start,end,offset) {
738 n = n + offset;
739 if (offset > 0 && n > end) {
740 n = start + (n - end - 1);
741 } else if (offset < 0 && n < start) {
742 n = end - (start - n - 1);
743 }
744 return String.fromCharCode(n);
745 }
746 // decrypt string
747 function decryptString(enc,offset) {
748 var dec = "";
749 var len = enc.length;
750 for(var i=0; i < len; i++) {
751 var n = enc.charCodeAt(i);
752 if (n >= 0x2B && n <= 0x3A) {
753 dec += decryptCharcode(n,0x2B,0x3A,offset); // 0-9 . , - + / :
754 } else if (n >= 0x40 && n <= 0x5A) {
755 dec += decryptCharcode(n,0x40,0x5A,offset); // A-Z @
756 } else if (n >= 0x61 && n <= 0x7A) {
757 dec += decryptCharcode(n,0x61,0x7A,offset); // a-z
758 } else {
759 dec += enc.charAt(i);
760 }
761 }
762 return dec;
763 }
764 // decrypt spam-protected emails
765 function linkTo_UnCryptMailto(s) {
766 location.href = decryptString(s,'.($GLOBALS['TSFE']->spamProtectEmailAddresses*-1).');
767 }
768 ';
769 }
770
771 if (!$GLOBALS['TSFE']->config['config']['removeDefaultJS']) {
772 // NOTICE: The following code must be kept synchronized with "tslib/default.js"!!!
773 $GLOBALS['TSFE']->content.='
774 <script type="text/javascript">
775 /*<![CDATA[*/
776 <!--'.$_scriptCode.'
777 // -->
778 /*]]>*/
779 </script>';
780 } elseif ($GLOBALS['TSFE']->config['config']['removeDefaultJS']==='external') {
781 $GLOBALS['TSFE']->content.= TSpagegen::inline2TempFile($_scriptCode, 'js');
782 }
783
784 $GLOBALS['TSFE']->content.= chr(10).implode($GLOBALS['TSFE']->additionalHeaderData,chr(10)).'
785 '.$JSef[0].'
786 </head>';
787 if ($GLOBALS['TSFE']->pSetup['frameSet.']) {
788 $fs = t3lib_div::makeInstance('tslib_frameset');
789 $GLOBALS['TSFE']->content.= $fs->make($GLOBALS['TSFE']->pSetup['frameSet.']);
790 $GLOBALS['TSFE']->content.= chr(10).'<noframes>'.chr(10);
791 }
792
793 // Bodytag:
794 $defBT = $GLOBALS['TSFE']->pSetup['bodyTagCObject'] ? $GLOBALS['TSFE']->cObj->cObjGetSingle($GLOBALS['TSFE']->pSetup['bodyTagCObject'],$GLOBALS['TSFE']->pSetup['bodyTagCObject.'],'bodyTagCObject') : '';
795 if (!$defBT) $defBT = $GLOBALS['TSFE']->defaultBodyTag;
796 $bodyTag = $GLOBALS['TSFE']->pSetup['bodyTag'] ? $GLOBALS['TSFE']->pSetup['bodyTag'] : $defBT;
797 if ($bgImg=$GLOBALS['TSFE']->cObj->getImgResource($GLOBALS['TSFE']->pSetup['bgImg'],$GLOBALS['TSFE']->pSetup['bgImg.'])) {
798 $bodyTag = ereg_replace('>$','',trim($bodyTag)).' background="'.$GLOBALS["TSFE"]->absRefPrefix.$bgImg[3].'">';
799 }
800
801 if (isset($GLOBALS['TSFE']->pSetup['bodyTagMargins'])) {
802 $margins = intval($GLOBALS['TSFE']->pSetup['bodyTagMargins']);
803 if ($GLOBALS['TSFE']->pSetup['bodyTagMargins.']['useCSS']) {
804 // Setting margins in CSS, see above
805 } else {
806 $bodyTag = ereg_replace('>$','',trim($bodyTag)).' leftmargin="'.$margins.'" topmargin="'.$margins.'" marginwidth="'.$margins.'" marginheight="'.$margins.'">';
807 }
808 }
809
810 if (trim($GLOBALS['TSFE']->pSetup['bodyTagAdd'])) {
811 $bodyTag = ereg_replace('>$','',trim($bodyTag)).' '.trim($GLOBALS['TSFE']->pSetup['bodyTagAdd']).'>';
812 }
813
814 if (count($JSef[1])) { // Event functions:
815 $bodyTag = ereg_replace('>$','',trim($bodyTag)).' '.trim(implode(' ',$JSef[1])).'>';
816 }
817 $GLOBALS['TSFE']->content.= chr(10).$bodyTag;
818
819
820 // Div-sections
821 if ($GLOBALS['TSFE']->divSection) {
822 $GLOBALS['TSFE']->content.= chr(10).$GLOBALS['TSFE']->divSection;
823 }
824
825 // Page content
826 $GLOBALS['TSFE']->content.= chr(10).$pageContent;
827
828 // Ending page
829 $GLOBALS['TSFE']->content.= chr(10).'</body>';
830 if ($GLOBALS['TSFE']->pSetup['frameSet.']) {
831 $GLOBALS['TSFE']->content.= chr(10).'</noframes>';
832 }
833 $GLOBALS['TSFE']->content.=chr(10).'</html>';
834 }
835
836
837
838
839
840
841
842
843
844
845
846
847
848 /*************************
849 *
850 * Helper functions
851 * Remember: Calls internally must still be done on the non-instantiated class: TSpagegen::inline2TempFile()
852 *
853 *************************/
854
855 /**
856 * Writes string to a temporary file named after the md5-hash of the string
857 *
858 * @param string CSS styles / JavaScript to write to file.
859 * @param string Extension: "css" or "js"
860 * @return string <script> or <link> tag for the file.
861 */
862 function inline2TempFile($str,$ext) {
863
864 // Create filename / tags:
865 $script = '';
866 switch($ext) {
867 case 'js':
868 $script = 'typo3temp/javascript_'.substr(md5($str),0,10).'.js';
869 $output = '
870 <script type="text/javascript" src="'.htmlspecialchars($GLOBALS['TSFE']->absRefPrefix.$script).'"></script>';
871 break;
872 case 'css':
873 $script = 'typo3temp/stylesheet_'.substr(md5($str),0,10).'.css';
874 $output = '
875 <link rel="stylesheet" type="text/css" href="'.htmlspecialchars($GLOBALS['TSFE']->absRefPrefix.$script).'" />';
876 break;
877 }
878
879 // Write file:
880 if ($script) {
881 if (!@is_file(PATH_site.$script)) {
882 t3lib_div::writeFile(PATH_site.$script,$str);
883 }
884 }
885
886 return $output;
887 }
888
889 /**
890 * 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.
891 *
892 * @param string The string in which to find $needle
893 * @param string The string to find in $haystack
894 * @return boolean Returns true if $needle matches or is found in $haystack
895 */
896 function isAllowedLinkVarValue($haystack,$needle) {
897 $OK = false;
898
899 if ($needle=='int' || $needle=='integer') { // Integer
900
901 if (t3lib_div::testInt($haystack)) {
902 $OK = true;
903 }
904
905 } elseif (preg_match('/^\/.+\/[imsxeADSUXu]*$/', $needle)) { // Regular expression, only "//" is allowed as delimiter
906
907 if (@preg_match($needle, $haystack)) {
908 $OK = true;
909 }
910
911 } elseif (strstr($needle,'-')) { // Range
912
913 if (t3lib_div::testInt($haystack)) {
914 $range = explode('-',$needle);
915 if ($range[0] <= $haystack && $range[1] >= $haystack) {
916 $OK = true;
917 }
918 }
919
920 } elseif (strstr($needle,'|')) { // List
921
922 $haystack = str_replace(' ','',$haystack); // Trim the input
923 if (strstr('|'.$needle.'|', '|'.$haystack.'|')) {
924 $OK = true;
925 }
926
927 } elseif (!strcmp($needle,$haystack)) { // String comparison
928 $OK = true;
929 }
930
931 return $OK;
932 }
933 }
934
935 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_pagegen.php']) {
936 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['tslib/class.tslib_pagegen.php']);
937 }
938
939
940
941 // ********************************************************
942 // Includes the search-class if $sword and $scols are set.
943 // ********************************************************
944 if (t3lib_div::_GP('sword') && t3lib_div::_GP('scols')) {
945 require_once(PATH_tslib.'class.tslib_search.php');
946 }
947
948 // ************
949 // LoadDBGroup
950 // ************
951 require_once (PATH_t3lib.'class.t3lib_loaddbgroup.php');
952
953 /**
954 * Class for fetching record relations for the frontend.
955 *
956 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
957 * @package TYPO3
958 * @subpackage tslib
959 * @see tslib_cObj::RECORDS()
960 */
961 class FE_loadDBGroup extends t3lib_loadDBGroup {
962 var $fromTC = 0; // Means the not only uid and label-field is returned, but everything
963 }
964
965 // **********************************
966 // includes stuff for graphical work
967 // **********************************
968 require_once(PATH_t3lib.'class.t3lib_stdgraphic.php');
969 require_once(PATH_tslib.'class.tslib_gifbuilder.php');
970
971 // *************************
972 // includes menu-management
973 // *************************
974 require_once(PATH_tslib.'class.tslib_menu.php');
975
976 // *************************
977 // Global content object...
978 // *************************
979 require_once(PATH_tslib.'class.tslib_content.php');
980
981 ?>