dd4bcf55632f5149b272ed33901bf3f247c32c51
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / FrontendRequestHandler.php
1 <?php
2 namespace TYPO3\CMS\Frontend;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Frontend\Utility\EidUtility;
18
19 /**
20 * This is the MAIN DOCUMENT of the TypoScript driven standard front-end
21 *
22 * Basically put this is the script which all requests for TYPO3
23 * delivered pages goes to in the frontend (the website). The script configures
24 * constants, includes libraries and does a little logic here and there in order
25 * to instantiate the right classes to create the webpage.
26 */
27 class FrontendRequestHandler {
28
29 /**
30 * Handles a frontend request
31 *
32 * @return void
33 */
34 public function handleRequest() {
35 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()
36 ->loadTypo3LoadedExtAndExtLocalconf(TRUE)
37 ->applyAdditionalConfigurationSettings();
38
39 // Timetracking started
40 $configuredCookieName = trim($GLOBALS['TYPO3_CONF_VARS']['BE']['cookieName']);
41 if (empty($configuredCookieName)) {
42 $configuredCookieName = 'be_typo_user';
43 }
44 if ($_COOKIE[$configuredCookieName]) {
45 $GLOBALS['TT'] = new \TYPO3\CMS\Core\TimeTracker\TimeTracker();
46 } else {
47 $GLOBALS['TT'] = new \TYPO3\CMS\Core\TimeTracker\NullTimeTracker();
48 }
49
50 $GLOBALS['TT']->start();
51
52 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->initializeTypo3DbGlobal();
53 // Hook to preprocess the current request:
54 if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'])) {
55 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/index_ts.php']['preprocessRequest'] as $hookFunction) {
56 $hookParameters = array();
57 \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($hookFunction, $hookParameters, $hookParameters);
58 }
59 unset($hookFunction);
60 unset($hookParameters);
61 }
62 // Look for extension ID which will launch alternative output engine
63 if (EidUtility::isEidRequest()) {
64 // Remove any output produced until now
65 ob_clean();
66 require EidUtility::getEidScriptPath();
67 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->shutdown();
68 exit;
69 }
70
71 /** @var $GLOBALS['TSFE'] \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController */
72 $GLOBALS['TSFE'] = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
73 \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController::class,
74 $GLOBALS['TYPO3_CONF_VARS'],
75 \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('id'),
76 \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('type'),
77 \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('no_cache'),
78 \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('cHash'),
79 \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('jumpurl'),
80 \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('MP'),
81 \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('RDCT')
82 );
83
84 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['pageUnavailable_force']
85 && !\TYPO3\CMS\Core\Utility\GeneralUtility::cmpIP(
86 \TYPO3\CMS\Core\Utility\GeneralUtility::getIndpEnv('REMOTE_ADDR'),
87 $GLOBALS['TYPO3_CONF_VARS']['SYS']['devIPmask'])
88 ) {
89 $GLOBALS['TSFE']->pageUnavailableAndExit('This page is temporarily unavailable.');
90 }
91
92 $GLOBALS['TSFE']->connectToDB();
93 $GLOBALS['TSFE']->sendRedirect();
94
95 // Output compression
96 // Remove any output produced until now
97 ob_clean();
98 if ($GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'] && extension_loaded('zlib')) {
99 if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel'])) {
100 // Prevent errors if ini_set() is unavailable (safe mode)
101 @ini_set('zlib.output_compression_level', $GLOBALS['TYPO3_CONF_VARS']['FE']['compressionLevel']);
102 }
103 ob_start(array(\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Utility\CompressionUtility::class), 'compressionOutputHandler'));
104 }
105
106 // FE_USER
107 $GLOBALS['TT']->push('Front End user initialized', '');
108 /** @var $GLOBALS['TSFE'] \TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController */
109 $GLOBALS['TSFE']->initFEuser();
110 $GLOBALS['TT']->pull();
111
112 // BE_USER
113 /** @var $GLOBALS['BE_USER'] \TYPO3\CMS\Backend\FrontendBackendUserAuthentication */
114 $GLOBALS['BE_USER'] = $GLOBALS['TSFE']->initializeBackendUser();
115
116 // Process the ID, type and other parameters.
117 // After this point we have an array, $page in TSFE, which is the page-record
118 // of the current page, $id.
119 $GLOBALS['TT']->push('Process ID', '');
120 // Initialize admin panel since simulation settings are required here:
121 if ($GLOBALS['TSFE']->isBackendUserLoggedIn()) {
122 $GLOBALS['BE_USER']->initializeAdminPanel();
123 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadExtensionTables(TRUE);
124 } else {
125 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->loadCachedTca();
126 }
127 $GLOBALS['TSFE']->checkAlternativeIdMethods();
128 $GLOBALS['TSFE']->clear_preview();
129 $GLOBALS['TSFE']->determineId();
130
131 // Now, if there is a backend user logged in and he has NO access to this page,
132 // then re-evaluate the id shown! _GP('ADMCMD_noBeUser') is placed here because
133 // \TYPO3\CMS\Version\Hook\PreviewHook might need to know if a backend user is logged in.
134 if (
135 $GLOBALS['TSFE']->isBackendUserLoggedIn()
136 && (!$GLOBALS['BE_USER']->extPageReadAccess($GLOBALS['TSFE']->page) || \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('ADMCMD_noBeUser'))
137 ) {
138 // Remove user
139 unset($GLOBALS['BE_USER']);
140 $GLOBALS['TSFE']->beUserLogin = FALSE;
141 // Re-evaluate the page-id.
142 $GLOBALS['TSFE']->checkAlternativeIdMethods();
143 $GLOBALS['TSFE']->clear_preview();
144 $GLOBALS['TSFE']->determineId();
145 }
146
147 $GLOBALS['TSFE']->makeCacheHash();
148 $GLOBALS['TT']->pull();
149
150 // Admin Panel & Frontend editing
151 if ($GLOBALS['TSFE']->isBackendUserLoggedIn()) {
152 $GLOBALS['BE_USER']->initializeFrontendEdit();
153 if ($GLOBALS['BE_USER']->adminPanel instanceof \TYPO3\CMS\Frontend\View\AdminPanelView) {
154 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()
155 ->initializeLanguageObject()
156 ->initializeSpriteManager();
157 }
158 if ($GLOBALS['BE_USER']->frontendEdit instanceof \TYPO3\CMS\Core\FrontendEditing\FrontendEditingController) {
159 $GLOBALS['BE_USER']->frontendEdit->initConfigOptions();
160 }
161 }
162
163 // Starts the template
164 $GLOBALS['TT']->push('Start Template', '');
165 $GLOBALS['TSFE']->initTemplate();
166 $GLOBALS['TT']->pull();
167 // Get from cache
168 $GLOBALS['TT']->push('Get Page from cache', '');
169 $GLOBALS['TSFE']->getFromCache();
170 $GLOBALS['TT']->pull();
171 // Get config if not already gotten
172 // After this, we should have a valid config-array ready
173 $GLOBALS['TSFE']->getConfigArray();
174 // Setting language and locale
175 $GLOBALS['TT']->push('Setting language and locale', '');
176 $GLOBALS['TSFE']->settingLanguage();
177 $GLOBALS['TSFE']->settingLocale();
178 $GLOBALS['TT']->pull();
179
180 // Convert POST data to internal "renderCharset" if different from the metaCharset
181 $GLOBALS['TSFE']->convPOSTCharset();
182
183 // Check JumpUrl
184 $GLOBALS['TSFE']->setExternalJumpUrl();
185 $GLOBALS['TSFE']->checkJumpUrlReferer();
186
187 $GLOBALS['TSFE']->handleDataSubmission();
188
189 // Check for shortcut page and redirect
190 $GLOBALS['TSFE']->checkPageForShortcutRedirect();
191 $GLOBALS['TSFE']->checkPageForMountpointRedirect();
192
193 // Generate page
194 $GLOBALS['TSFE']->setUrlIdToken();
195 $GLOBALS['TT']->push('Page generation', '');
196 if ($GLOBALS['TSFE']->isGeneratePage()) {
197 $GLOBALS['TSFE']->generatePage_preProcessing();
198 $temp_theScript = $GLOBALS['TSFE']->generatePage_whichScript();
199 if ($temp_theScript) {
200 include $temp_theScript;
201 } else {
202 \TYPO3\CMS\Frontend\Page\PageGenerator::pagegenInit();
203 // Global content object
204 $GLOBALS['TSFE']->newCObj();
205 // LIBRARY INCLUSION, TypoScript
206 $temp_incFiles = \TYPO3\CMS\Frontend\Page\PageGenerator::getIncFiles();
207 foreach ($temp_incFiles as $temp_file) {
208 include_once './' . $temp_file;
209 }
210 // Content generation
211 if (!$GLOBALS['TSFE']->isINTincScript()) {
212 \TYPO3\CMS\Frontend\Page\PageGenerator::renderContent();
213 $GLOBALS['TSFE']->setAbsRefPrefix();
214 }
215 }
216 $GLOBALS['TSFE']->generatePage_postProcessing();
217 } elseif ($GLOBALS['TSFE']->isINTincScript()) {
218 \TYPO3\CMS\Frontend\Page\PageGenerator::pagegenInit();
219 // Global content object
220 $GLOBALS['TSFE']->newCObj();
221 // LIBRARY INCLUSION, TypoScript
222 $temp_incFiles = \TYPO3\CMS\Frontend\Page\PageGenerator::getIncFiles();
223 foreach ($temp_incFiles as $temp_file) {
224 include_once './' . $temp_file;
225 }
226 }
227 $GLOBALS['TT']->pull();
228
229 // $GLOBALS['TSFE']->config['INTincScript']
230 if ($GLOBALS['TSFE']->isINTincScript()) {
231 $GLOBALS['TT']->push('Non-cached objects', '');
232 $GLOBALS['TSFE']->INTincScript();
233 $GLOBALS['TT']->pull();
234 }
235 // Output content
236 $sendTSFEContent = FALSE;
237 if ($GLOBALS['TSFE']->isOutputting()) {
238 $GLOBALS['TT']->push('Print Content', '');
239 $GLOBALS['TSFE']->processOutput();
240 $sendTSFEContent = TRUE;
241 $GLOBALS['TT']->pull();
242 }
243 // Store session data for fe_users
244 $GLOBALS['TSFE']->storeSessionData();
245 // Statistics
246 $GLOBALS['TYPO3_MISC']['microtime_end'] = microtime(TRUE);
247 $GLOBALS['TSFE']->setParseTime();
248 if (isset($GLOBALS['TSFE']->config['config']['debug'])) {
249 $debugParseTime = (bool)$GLOBALS['TSFE']->config['config']['debug'];
250 } else {
251 $debugParseTime = !empty($GLOBALS['TSFE']->TYPO3_CONF_VARS['FE']['debug']);
252 }
253 if ($GLOBALS['TSFE']->isOutputting() && $debugParseTime) {
254 $GLOBALS['TSFE']->content .= LF . '<!-- Parsetime: ' . $GLOBALS['TSFE']->scriptParseTime . 'ms -->';
255 }
256 // Check JumpUrl
257 $GLOBALS['TSFE']->jumpurl();
258 // Preview info
259 $GLOBALS['TSFE']->previewInfo();
260 // Hook for end-of-frontend
261 $GLOBALS['TSFE']->hook_eofe();
262 // Finish timetracking
263 $GLOBALS['TT']->pull();
264 // Check memory usage
265 \TYPO3\CMS\Core\Utility\MonitorUtility::peakMemoryUsage();
266 // beLoginLinkIPList
267 echo $GLOBALS['TSFE']->beLoginLinkIPList();
268
269 // Admin panel
270 if (
271 $GLOBALS['TSFE']->isBackendUserLoggedIn()
272 && $GLOBALS['BE_USER'] instanceof \TYPO3\CMS\Backend\FrontendBackendUserAuthentication
273 && $GLOBALS['BE_USER']->isAdminPanelVisible()
274 ) {
275 $GLOBALS['TSFE']->content = str_ireplace('</head>', $GLOBALS['BE_USER']->adminPanel->getAdminPanelHeaderData() . '</head>', $GLOBALS['TSFE']->content);
276 $GLOBALS['TSFE']->content = str_ireplace('</body>', $GLOBALS['BE_USER']->displayAdminPanel() . '</body>', $GLOBALS['TSFE']->content);
277 }
278
279 if ($sendTSFEContent) {
280 echo $GLOBALS['TSFE']->content;
281 }
282 // Debugging Output
283 if (isset($GLOBALS['error']) && is_object($GLOBALS['error']) && @is_callable(array($GLOBALS['error'], 'debugOutput'))) {
284 $GLOBALS['error']->debugOutput();
285 }
286 if (TYPO3_DLOG) {
287 \TYPO3\CMS\Core\Utility\GeneralUtility::devLog('END of FRONTEND session', 'cms', 0, array('_FLUSH' => TRUE));
288 }
289 \TYPO3\CMS\Core\Core\Bootstrap::getInstance()->shutdown();
290 }
291
292 }