TYPO3 CMS  TYPO3_8-7
AddController.php
Go to the documentation of this file.
1 <?php
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 
27 
33 {
39  public $content;
40 
46  public $processDataFlag = 0;
47 
53  public $pid;
54 
60  public $table;
61 
67  public $id;
68 
74  public $P;
75 
82 
86  public function __construct()
87  {
88  parent::__construct();
89  $this->getLanguageService()->includeLLFile('EXT:lang/Resources/Private/Language/locallang_wizards.xlf');
90  $GLOBALS['SOBE'] = $this;
91 
92  $this->init();
93  }
94 
98  protected function init()
99  {
100  // Init GPvars:
101  $this->P = GeneralUtility::_GP('P');
102  $this->returnEditConf = GeneralUtility::_GP('returnEditConf');
103  // Get this record
104  $record = BackendUtility::getRecord($this->P['table'], $this->P['uid']);
105  // Set table:
106  $this->table = $this->P['params']['table'];
107  // Get TSconfig for it.
109  $this->P['table'],
110  is_array($record) ? $record : ['pid' => $this->P['pid']]
111  );
112  // Set [params][pid]
113  if (substr($this->P['params']['pid'], 0, 3) === '###' && substr($this->P['params']['pid'], -3) === '###') {
114  $keyword = substr($this->P['params']['pid'], 3, -3);
115  if (strpos($keyword, 'PAGE_TSCONFIG_') === 0) {
116  $this->pid = (int)$TSconfig[$this->P['field']][$keyword];
117  } else {
118  $this->pid = (int)$TSconfig['_' . $keyword];
119  }
120  } else {
121  $this->pid = (int)$this->P['params']['pid'];
122  }
123  // Return if new record as parent (not possibly/allowed)
124  if ($this->pid === '') {
126  }
127  // Else proceed:
128  // If a new id has returned from a newly created record...
129  if ($this->returnEditConf) {
130  $editConfiguration = json_decode($this->returnEditConf, true);
131  if (is_array($editConfiguration[$this->table]) && MathUtility::canBeInterpretedAsInteger($this->P['uid'])) {
132  // Getting id and cmd from returning editConf array.
133  reset($editConfiguration[$this->table]);
134  $this->id = (int)key($editConfiguration[$this->table]);
135  $cmd = current($editConfiguration[$this->table]);
136  // ... and if everything seems OK we will register some classes for inclusion and instruct the object
137  // to perform processing later.
138  if ($this->P['params']['setValue']
139  && $cmd === 'edit'
140  && $this->id
141  && $this->P['table']
142  && $this->P['field'] && $this->P['uid']
143  ) {
144  $liveRecord = BackendUtility::getLiveVersionOfRecord($this->table, $this->id, 'uid');
145  if ($liveRecord) {
146  $this->id = $liveRecord['uid'];
147  }
148  $this->processDataFlag = 1;
149  }
150  }
151  }
152  }
153 
162  public function mainAction(ServerRequestInterface $request, ResponseInterface $response)
163  {
164  $this->main();
165  return $response;
166  }
167 
172  public function main()
173  {
174  if ($this->returnEditConf) {
175  if ($this->processDataFlag) {
176  // Because OnTheFly can't handle MM relations with intermediate tables we use TcaDatabaseRecord here
177  // Otherwise already stored relations are overwritten with the new entry
179  $formDataGroup = GeneralUtility::makeInstance(TcaDatabaseRecord::class);
181  $formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class, $formDataGroup);
182  $input = [
183  'tableName' => $this->P['table'],
184  'vanillaUid' => (int)$this->P['uid'],
185  'command' => 'edit',
186  ];
187  $result = $formDataCompiler->compile($input);
188  $currentParentRow = $result['databaseRow'];
189 
190  // If that record was found (should absolutely be...), then init DataHandler and set, prepend or append
191  // the record
192  if (is_array($currentParentRow)) {
194  $dataHandler = GeneralUtility::makeInstance(DataHandler::class);
195  $data = [];
196  $recordId = $this->table . '_' . $this->id;
197  // Setting the new field data:
198  // If the field is a flexForm field, work with the XML structure instead:
199  if ($this->P['flexFormPath']) {
200  // Current value of flexForm path:
201  $currentFlexFormData = $currentParentRow[$this->P['field']];
203  $flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
204  $currentFlexFormValueByPath = $flexFormTools->getArrayValueByPath(
205  $this->P['flexFormPath'],
206  $currentFlexFormData
207  );
208 
209  // Compile currentFlexFormData to functional string
210  $currentFlexFormValues = [];
211  foreach ($currentFlexFormValueByPath as $value) {
212  if (is_array($value)) {
213  // group fields are always resolved to array
214  $currentFlexFormValues[] = $value['table'] . '_' . $value['uid'];
215  } else {
216  // but select fields may be uids only
217  $currentFlexFormValues[] = $value;
218  }
219  }
220  $currentFlexFormValue = implode(',', $currentFlexFormValues);
221 
222  $insertValue = '';
223  switch ((string)$this->P['params']['setValue']) {
224  case 'set':
225  $insertValue = $recordId;
226  break;
227  case 'append':
228  $insertValue = $currentFlexFormValue . ',' . $recordId;
229  break;
230  case 'prepend':
231  $insertValue = $recordId . ',' . $currentFlexFormValue;
232  break;
233  }
234  $insertValue = implode(',', GeneralUtility::trimExplode(',', $insertValue, true));
235  $data[$this->P['table']][$this->P['uid']][$this->P['field']] = [];
236  $flexFormTools->setArrayValueByPath(
237  $this->P['flexFormPath'],
238  $data[$this->P['table']][$this->P['uid']][$this->P['field']],
239  $insertValue
240  );
241  } else {
242  $currentValue = $currentParentRow[$this->P['field']];
243 
244  // Normalize CSV values
245  if (!is_array($currentValue)) {
246  $currentValue = GeneralUtility::trimExplode(',', $currentValue, true);
247  }
248 
249  // Normalize all items to "<table>_<uid>" format
250  $currentValue = array_map(function ($item) {
251  // Handle per-item table for "group" elements
252  if (is_array($item)) {
253  $item = $item['table'] . '_' . $item['uid'];
254  } else {
255  $item = $this->table . '_' . $item;
256  }
257 
258  return $item;
259  }, $currentValue);
260 
261  switch ((string)$this->P['params']['setValue']) {
262  case 'set':
263  $currentValue = [$recordId];
264  break;
265  case 'append':
266  $currentValue[] = $recordId;
267  break;
268  case 'prepend':
269  array_unshift($currentValue, $recordId);
270  break;
271  }
272 
273  $data[$this->P['table']][$this->P['uid']][$this->P['field']] = implode(',', $currentValue);
274  }
275  // Submit the data:
276  $dataHandler->start($data, []);
277  $dataHandler->process_datamap();
278  }
279  }
280  // Return to the parent FormEngine record editing session:
282  } else {
283  // Redirecting to FormEngine with instructions to create a new record
284  // AND when closing to return back with information about that records ID etc.
285  $redirectUrl = BackendUtility::getModuleUrl('record_edit', [
286  'returnEditConf' => 1,
287  'edit[' . $this->P['params']['table'] . '][' . $this->pid . ']' => 'new',
288  'returnUrl' => GeneralUtility::getIndpEnv('REQUEST_URI')
289  ]);
290  HttpUtility::redirect($redirectUrl);
291  }
292  }
293 }
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
static makeInstance($className,... $constructorArguments)
mainAction(ServerRequestInterface $request, ResponseInterface $response)
static redirect($url, $httpStatus=self::HTTP_STATUS_303)
static getLiveVersionOfRecord($table, $uid, $fields=' *')
static getRecord($table, $uid, $fields=' *', $where='', $useDeleteClause=true)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']