[TASK] Bootstrap: Load TCA configuration on every request
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Http / AjaxRequestHandler.php
1 <?php
2 namespace TYPO3\CMS\Backend\Http;
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 Psr\Http\Message\ResponseInterface;
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Backend\Routing\Exception\InvalidRequestTokenException;
20 use TYPO3\CMS\Backend\Routing\Exception\ResourceNotFoundException;
21 use TYPO3\CMS\Core\Core\Bootstrap;
22 use TYPO3\CMS\Core\Http\RequestHandlerInterface;
23 use TYPO3\CMS\Core\Http\Response;
24 use TYPO3\CMS\Core\Utility\GeneralUtility;
25
26 /**
27 * AJAX dispatcher
28 *
29 * Main entry point for AJAX calls in the TYPO3 Backend. Based on ?ajaxId of the outside application.
30 * Before doing the basic BE-related set up of this request (see the additional calls on $this->bootstrap inside
31 * handleRequest()), some AJAX-calls can be made without a valid user, which is determined here.
32 *
33 * AJAX Requests are typically registered within EXT:myext/Configuration/Backend/AjaxRoutes.php
34 */
35 class AjaxRequestHandler implements RequestHandlerInterface
36 {
37 /**
38 * Instance of the current TYPO3 bootstrap
39 * @var Bootstrap
40 */
41 protected $bootstrap;
42
43 /**
44 * List of requests that don't need a valid BE user
45 * @var array
46 */
47 protected $publicAjaxIds = [
48 '/ajax/login',
49 '/ajax/logout',
50 '/ajax/login/refresh',
51 '/ajax/login/timedout',
52 '/ajax/rsa/publickey'
53 ];
54
55 /**
56 * Constructor handing over the bootstrap and the original request
57 *
58 * @param Bootstrap $bootstrap
59 */
60 public function __construct(Bootstrap $bootstrap)
61 {
62 $this->bootstrap = $bootstrap;
63 }
64
65 /**
66 * Handles any AJAX request in the TYPO3 Backend
67 *
68 * @param ServerRequestInterface $request
69 * @return NULL|\Psr\Http\Message\ResponseInterface
70 */
71 public function handleRequest(ServerRequestInterface $request)
72 {
73 // First get the ajaxID
74 $ajaxID = isset($request->getParsedBody()['ajaxID']) ? $request->getParsedBody()['ajaxID'] : $request->getQueryParams()['ajaxID'];
75 $request = $request->withAttribute('routePath', $ajaxID);
76 $proceedIfNoUserIsLoggedIn = $this->isLoggedInBackendUserRequired($ajaxID);
77 $this->boot($proceedIfNoUserIsLoggedIn);
78
79 // Backend Routing - check if a valid route is there, and dispatch
80 return $this->dispatch($request);
81 }
82
83 /**
84 * This request handler can handle any backend request having
85 * an ajaxID as parameter (see Application.php in EXT:backend)
86 *
87 * @param ServerRequestInterface $request
88 * @return bool If the request is an AJAX backend request, TRUE otherwise FALSE
89 */
90 public function canHandleRequest(ServerRequestInterface $request)
91 {
92 return $request->getAttribute('isAjaxRequest', false);
93 }
94
95 /**
96 * Returns the priority - how eager the handler is to actually handle the request.
97 *
98 * @return int The priority of the request handler.
99 */
100 public function getPriority()
101 {
102 return 80;
103 }
104
105 /**
106 * Check if the user is required for the request
107 * If we're trying to do an ajax login, don't require a user
108 *
109 * @param string $ajaxId the Ajax ID to check against
110 * @return bool whether the request can proceed without a login required
111 */
112 protected function isLoggedInBackendUserRequired($ajaxId)
113 {
114 return in_array($ajaxId, $this->publicAjaxIds, true);
115 }
116
117 /**
118 * Start the Backend bootstrap part
119 *
120 * @param bool $proceedIfNoUserIsLoggedIn a flag if a backend user is required
121 */
122 protected function boot($proceedIfNoUserIsLoggedIn)
123 {
124 $this->bootstrap
125 ->checkLockedBackendAndRedirectOrDie($proceedIfNoUserIsLoggedIn)
126 ->checkBackendIpOrDie()
127 ->checkSslBackendAndRedirectIfNeeded()
128 ->initializeBackendRouter()
129 ->loadExtTables()
130 ->initializeBackendUser()
131 ->initializeBackendAuthentication($proceedIfNoUserIsLoggedIn)
132 ->initializeLanguageObject()
133 ->initializeBackendTemplate()
134 ->endOutputBufferingAndCleanPreviousOutput()
135 ->initializeOutputCompression()
136 ->sendHttpHeaders();
137 }
138
139 /**
140 * Creates a response object with JSON headers automatically, and then dispatches to the correct route
141 *
142 * @param ServerRequestInterface $request
143 * @return ResponseInterface $response
144 * @throws ResourceNotFoundException if no valid route was found
145 * @throws InvalidRequestTokenException if the request could not be verified
146 */
147 protected function dispatch(ServerRequestInterface $request)
148 {
149 /** @var Response $response */
150 $response = GeneralUtility::makeInstance(Response::class, 'php://temp', 200, [
151 'Content-Type' => 'application/json; charset=utf-8',
152 'X-JSON' => 'true'
153 ]);
154
155 /** @var RouteDispatcher $dispatcher */
156 $dispatcher = GeneralUtility::makeInstance(RouteDispatcher::class);
157 return $dispatcher->dispatch($request, $response);
158 }
159 }