[TASK] Streamline hooks and middlewares related to PSR-15
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Classes / Middleware / PrepareTypoScriptFrontendRendering.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Frontend\Middleware;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use Psr\Http\Message\ResponseInterface;
20 use Psr\Http\Message\ServerRequestInterface;
21 use Psr\Http\Server\MiddlewareInterface;
22 use Psr\Http\Server\RequestHandlerInterface as PsrRequestHandlerInterface;
23 use TYPO3\CMS\Core\TimeTracker\TimeTracker;
24 use TYPO3\CMS\Core\Utility\ArrayUtility;
25 use TYPO3\CMS\Core\Utility\GeneralUtility;
26 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
27
28 /**
29 * Initialization of TypoScriptFrontendController
30 *
31 * Do all necessary preparation steps for rendering
32 *
33 * @internal this middleware might get removed in TYPO3 v10.0.
34 */
35 class PrepareTypoScriptFrontendRendering implements MiddlewareInterface
36 {
37 /**
38 * @var TypoScriptFrontendController
39 */
40 protected $controller;
41
42 /**
43 * @var TimeTracker
44 */
45 protected $timeTracker;
46
47 public function __construct(TypoScriptFrontendController $controller = null, TimeTracker $timeTracker = null)
48 {
49 $this->controller = $controller ?: $GLOBALS['TSFE'];
50 $this->timeTracker = $timeTracker ?: GeneralUtility::makeInstance(TimeTracker::class);
51 }
52
53 /**
54 * Initialize TypoScriptFrontendController to the point right before rendering of the page is triggered
55 *
56 * @param ServerRequestInterface $request
57 * @param PsrRequestHandlerInterface $handler
58 * @return ResponseInterface
59 */
60 public function process(ServerRequestInterface $request, PsrRequestHandlerInterface $handler): ResponseInterface
61 {
62 // Get from cache
63 $this->timeTracker->push('Get Page from cache');
64 // Locks may be acquired here
65 $this->controller->getFromCache();
66 $this->timeTracker->pull();
67 // Get config if not already gotten
68 // After this, we should have a valid config-array ready
69 $this->controller->getConfigArray();
70
71 // Merge Query Parameters with config.defaultGetVars
72 // This is done in getConfigArray as well, but does not override the current middleware request object
73 // Since we want to stay in sync with this, the option needs to be set as well.
74 if (!empty($this->controller->config['config']['defaultGetVars.'] ?? null)) {
75 $modifiedGetVars = GeneralUtility::removeDotsFromTS($this->controller->config['config']['defaultGetVars.']);
76 if (!empty($request->getQueryParams())) {
77 ArrayUtility::mergeRecursiveWithOverrule($modifiedGetVars, $request->getQueryParams());
78 }
79 $request = $request->withQueryParams($modifiedGetVars);
80 $GLOBALS['TYPO3_REQUEST'] = $request;
81 }
82
83 // Setting language and locale
84 $this->timeTracker->push('Setting language and locale');
85 $this->controller->settingLanguage();
86 $this->controller->settingLocale();
87 $this->timeTracker->pull();
88
89 // Convert POST data to utf-8 for internal processing if metaCharset is different
90 if ($this->controller->metaCharset !== 'utf-8' && is_array($_POST) && !empty($_POST)) {
91 $this->convertCharsetRecursivelyToUtf8($_POST, $this->controller->metaCharset);
92 $GLOBALS['HTTP_POST_VARS'] = $_POST;
93 $parsedBody = $request->getParsedBody();
94 $this->convertCharsetRecursivelyToUtf8($parsedBody, $this->controller->metaCharset);
95 $request = $request->withParsedBody($parsedBody);
96 $GLOBALS['TYPO3_REQUEST'] = $request;
97 }
98
99 // @deprecated since TYPO3 v9.3, will be removed in TYPO3 v10.0
100 $this->controller->initializeRedirectUrlHandlers(true);
101
102 // Hook for processing data submission to extensions
103 // This is done at this point, because we need the config values
104 if (!empty($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission'])) {
105 trigger_error('The "checkDataSubmission" hook will be removed in TYPO3 v10.0 in favor of PSR-15. Use a middleware instead.', E_USER_DEPRECATED);
106 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['checkDataSubmission'] as $className) {
107 GeneralUtility::makeInstance($className)->checkDataSubmission($this->controller);
108 }
109 }
110
111 return $handler->handle($request);
112 }
113
114 /**
115 * Small helper function to convert charsets for arrays to UTF-8
116 *
117 * @param mixed $data given by reference (string/array usually)
118 * @param string $fromCharset convert FROM this charset
119 */
120 protected function convertCharsetRecursivelyToUtf8(&$data, string $fromCharset)
121 {
122 foreach ($data as $key => $value) {
123 if (is_array($data[$key])) {
124 $this->convertCharsetRecursivelyToUtf8($data[$key], $fromCharset);
125 } elseif (is_string($data[$key])) {
126 $data[$key] = mb_convert_encoding($data[$key], 'utf-8', $fromCharset);
127 }
128 }
129 }
130 }