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