eb931ba09811fcd41a0cd4126eec071e6c178573
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Classes / Controller / SimpleDataHandlerController.php
1 <?php
2 namespace TYPO3\CMS\Backend\Controller;
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\Core\Messaging\AbstractMessage;
18 use TYPO3\CMS\Core\Utility\GeneralUtility;
19 use TYPO3\CMS\Core\DataHandling\DataHandler;
20 use TYPO3\CMS\Core\Utility\MathUtility;
21 use TYPO3\CMS\Backend\Clipboard\Clipboard;
22 use TYPO3\CMS\Backend\Utility\BackendUtility;
23 use TYPO3\CMS\Core\Utility\HttpUtility;
24 use TYPO3\CMS\Core\Http\AjaxRequestHandler;
25 use TYPO3\CMS\Core\Messaging\FlashMessageService;
26
27 /**
28 * Script Class, creating object of \TYPO3\CMS\Core\DataHandling\DataHandler and
29 * sending the posted data to the object.
30 *
31 * Used by many smaller forms/links in TYPO3, including the QuickEdit module.
32 * Is not used by FormEngine though (main form rendering script) - that uses the same class (TCEmain) but makes its own initialization (to save the redirect request).
33 * For all other cases than FormEngine it is recommended to use this script for submitting your editing forms - but the best solution in any case would probably be to link your application to FormEngine, that will give you easy form-rendering as well.
34 */
35 class SimpleDataHandlerController {
36
37 /**
38 * Array. Accepts options to be set in TCE object. Currently it supports "reverseOrder" (bool).
39 *
40 * @var array
41 */
42 public $flags;
43
44 /**
45 * Data array on the form [tablename][uid][fieldname] = value
46 *
47 * @var array
48 */
49 public $data;
50
51 /**
52 * Command array on the form [tablename][uid][command] = value.
53 * This array may get additional data set internally based on clipboard commands send in CB var!
54 *
55 * @var array
56 */
57 public $cmd;
58
59 /**
60 * Array passed to ->setMirror.
61 *
62 * @var array
63 */
64 public $mirror;
65
66 /**
67 * Cache command sent to ->clear_cacheCmd
68 *
69 * @var string
70 */
71 public $cacheCmd;
72
73 /**
74 * Redirect URL. Script will redirect to this location after performing operations (unless errors has occurred)
75 *
76 * @var string
77 */
78 public $redirect;
79
80 /**
81 * Boolean. If set, errors will be printed on screen instead of redirection. Should always be used, otherwise you will see no errors if they happen.
82 *
83 * @var int
84 */
85 public $prErr;
86
87 /**
88 * Clipboard command array. May trigger changes in "cmd"
89 *
90 * @var array
91 */
92 public $CB;
93
94 /**
95 * Verification code
96 *
97 * @var string
98 */
99 public $vC;
100
101 /**
102 * Boolean. Update Page Tree Trigger. If set and the manipulated records are pages then the update page tree signal will be set.
103 *
104 * @var int
105 */
106 public $uPT;
107
108 /**
109 * TYPO3 Core Engine
110 *
111 * @var \TYPO3\CMS\Core\DataHandling\DataHandler
112 */
113 public $tce;
114
115 /**
116 * Constructor
117 */
118 public function __construct() {
119 $GLOBALS['SOBE'] = $this;
120 $this->init();
121 }
122
123 /**
124 * Initialization of the class
125 *
126 * @return void
127 */
128 public function init() {
129 $beUser = $this->getBackendUser();
130 // GPvars:
131 $this->flags = GeneralUtility::_GP('flags');
132 $this->data = GeneralUtility::_GP('data');
133 $this->cmd = GeneralUtility::_GP('cmd');
134 $this->mirror = GeneralUtility::_GP('mirror');
135 $this->cacheCmd = GeneralUtility::_GP('cacheCmd');
136 $this->redirect = GeneralUtility::sanitizeLocalUrl(GeneralUtility::_GP('redirect'));
137 $this->prErr = GeneralUtility::_GP('prErr');
138 $this->CB = GeneralUtility::_GP('CB');
139 $this->vC = GeneralUtility::_GP('vC');
140 $this->uPT = GeneralUtility::_GP('uPT');
141 // Creating TCEmain object
142 $this->tce = GeneralUtility::makeInstance(DataHandler::class);
143 $this->tce->stripslashes_values = 0;
144 // Configuring based on user prefs.
145 if ($beUser->uc['recursiveDelete']) {
146 // TRUE if the delete Recursive flag is set.
147 $this->tce->deleteTree = 1;
148 }
149 if ($beUser->uc['copyLevels']) {
150 // Set to number of page-levels to copy.
151 $this->tce->copyTree = MathUtility::forceIntegerInRange($beUser->uc['copyLevels'], 0, 100);
152 }
153 if ($beUser->uc['neverHideAtCopy']) {
154 $this->tce->neverHideAtCopy = 1;
155 }
156 $TCAdefaultOverride = $beUser->getTSConfigProp('TCAdefaults');
157 if (is_array($TCAdefaultOverride)) {
158 $this->tce->setDefaultsFromUserTS($TCAdefaultOverride);
159 }
160 // Reverse order.
161 if ($this->flags['reverseOrder']) {
162 $this->tce->reverseOrder = 1;
163 }
164 }
165
166 /**
167 * Clipboard pasting and deleting.
168 *
169 * @return void
170 */
171 public function initClipboard() {
172 if (is_array($this->CB)) {
173 $clipObj = GeneralUtility::makeInstance(Clipboard::class);
174 $clipObj->initializeClipboard();
175 if ($this->CB['paste']) {
176 $clipObj->setCurrentPad($this->CB['pad']);
177 $this->cmd = $clipObj->makePasteCmdArray(
178 $this->CB['paste'],
179 $this->cmd,
180 isset($this->CB['update']) ? $this->CB['update'] : NULL
181 );
182 }
183 if ($this->CB['delete']) {
184 $clipObj->setCurrentPad($this->CB['pad']);
185 $this->cmd = $clipObj->makeDeleteCmdArray($this->cmd);
186 }
187 }
188 }
189
190 /**
191 * Executing the posted actions ...
192 *
193 * @return void
194 */
195 public function main() {
196 // LOAD TCEmain with data and cmd arrays:
197 $this->tce->start($this->data, $this->cmd);
198 if (is_array($this->mirror)) {
199 $this->tce->setMirror($this->mirror);
200 }
201 // Checking referer / executing
202 $refInfo = parse_url(GeneralUtility::getIndpEnv('HTTP_REFERER'));
203 $httpHost = GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY');
204 if ($httpHost != $refInfo['host'] && $this->vC != $this->getBackendUser()->veriCode() && !$GLOBALS['TYPO3_CONF_VARS']['SYS']['doNotCheckReferer']) {
205 $this->tce->log('', 0, 0, 0, 1, 'Referer host "%s" and server host "%s" did not match and veriCode was not valid either!', 1, array($refInfo['host'], $httpHost));
206 } else {
207 // Register uploaded files
208 $this->tce->process_uploads($_FILES);
209 // Execute actions:
210 $this->tce->process_datamap();
211 $this->tce->process_cmdmap();
212 // Clearing cache:
213 if (!empty($this->cacheCmd)) {
214 $this->tce->clear_cacheCmd($this->cacheCmd);
215 }
216 // Update page tree?
217 if ($this->uPT && (isset($this->data['pages']) || isset($this->cmd['pages']))) {
218 BackendUtility::setUpdateSignal('updatePageTree');
219 }
220 }
221 }
222
223 /**
224 * Redirecting the user after the processing has been done.
225 * Might also display error messages directly, if any.
226 *
227 * @return void
228 */
229 public function finish() {
230 // Prints errors, if...
231 if ($this->prErr) {
232 $this->tce->printLogErrorMessages($this->redirect);
233 }
234 if ($this->redirect) {
235 HttpUtility::redirect($this->redirect);
236 }
237 }
238
239 /**
240 * Processes all AJAX calls and returns a JSON formatted string
241 *
242 * @param array $parameters
243 * @param \TYPO3\CMS\Core\Http\AjaxRequestHandler $ajaxRequestHandler
244 */
245 public function processAjaxRequest($parameters, AjaxRequestHandler $ajaxRequestHandler) {
246 // do the regular / main logic
247 $this->initClipboard();
248 $this->main();
249
250 /** @var \TYPO3\CMS\Core\Messaging\FlashMessageService $flashMessageService */
251 $flashMessageService = GeneralUtility::makeInstance(FlashMessageService::class);
252
253 $content = array(
254 'redirect' => $this->redirect,
255 'messages' => array(),
256 'hasErrors' => FALSE
257 );
258
259 // Prints errors (= write them to the message queue)
260 if ($this->prErr) {
261 $content['hasErrors'] = TRUE;
262 $this->tce->printLogErrorMessages($this->redirect);
263 }
264
265 $messages = $flashMessageService->getMessageQueueByIdentifier()->getAllMessagesAndFlush();
266 if (!empty($messages)) {
267 foreach ($messages as $message) {
268 $content['messages'][] = array(
269 'title' => $message->getTitle(),
270 'message' => $message->getMessage(),
271 'severity' => $message->getSeverity()
272 );
273 if ($message->getSeverity() === AbstractMessage::ERROR) {
274 $content['hasErrors'] = TRUE;
275 }
276 }
277 }
278 $ajaxRequestHandler->setContentFormat('json');
279 $ajaxRequestHandler->setContent($content);
280 }
281
282 /**
283 * Returns the current BE user.
284 *
285 * @return \TYPO3\CMS\Core\Authentication\BackendUserAuthentication
286 */
287 protected function getBackendUser() {
288 return $GLOBALS['BE_USER'];
289 }
290
291 }