init($request); if ($this->returnEditConf) { if ($this->processDataFlag) { // Because OnTheFly can't handle MM relations with intermediate tables we use TcaDatabaseRecord here // Otherwise already stored relations are overwritten with the new entry $input = [ 'request' => $request, 'tableName' => $this->P['table'], 'vanillaUid' => (int)$this->P['uid'], 'command' => 'edit', ]; $result = $this->formDataCompiler->compile($input, GeneralUtility::makeInstance(TcaDatabaseRecord::class)); $currentParentRow = $result['databaseRow']; // If that record was found (should absolutely be...), then init DataHandler and set, prepend or append // the record if (is_array($currentParentRow)) { $dataHandler = GeneralUtility::makeInstance(DataHandler::class); $data = []; $recordId = $this->table . '_' . $this->id; // Setting the new field data: // If the field is a flexForm field, work with the XML structure instead: if ($this->P['flexFormPath']) { // Current value of flexForm path: $currentFlexFormData = $currentParentRow[$this->P['field']]; $currentFlexFormValueByPath = ArrayUtility::getValueByPath($currentFlexFormData, $this->P['flexFormPath']); // Compile currentFlexFormData to functional string $currentFlexFormValues = []; foreach ($currentFlexFormValueByPath as $value) { if (is_array($value)) { // group fields are always resolved to array $currentFlexFormValues[] = $value['table'] . '_' . $value['uid']; } else { // but select fields may be uids only $currentFlexFormValues[] = $value; } } $currentFlexFormValue = implode(',', $currentFlexFormValues); $insertValue = ''; switch ((string)$this->P['params']['setValue']) { case 'set': $insertValue = $recordId; break; case 'append': $insertValue = $currentFlexFormValue . ',' . $recordId; break; case 'prepend': $insertValue = $recordId . ',' . $currentFlexFormValue; break; } $insertValue = implode(',', GeneralUtility::trimExplode(',', $insertValue, true)); $data[$this->P['table']][$this->P['uid']][$this->P['field']] = ArrayUtility::setValueByPath([], $this->P['flexFormPath'], $insertValue); } else { $currentValue = $currentParentRow[$this->P['field']]; // Normalize CSV values if (!is_array($currentValue)) { $currentValue = GeneralUtility::trimExplode(',', $currentValue, true); } // Normalize all items to "_" format $currentValue = array_map(function (array|int|string $item): string { // Handle per-item table for "group" elements if (is_array($item)) { $item = $item['table'] . '_' . $item['uid']; } else { $item = $this->table . '_' . $item; } return $item; }, $currentValue); switch ((string)$this->P['params']['setValue']) { case 'set': $currentValue = [$recordId]; break; case 'append': $currentValue[] = $recordId; break; case 'prepend': array_unshift($currentValue, $recordId); break; } $data[$this->P['table']][$this->P['uid']][$this->P['field']] = implode(',', $currentValue); } // Submit the data: $dataHandler->start($data, []); $dataHandler->process_datamap(); } } // Return to the parent FormEngine record editing session: return new RedirectResponse(GeneralUtility::sanitizeLocalUrl($this->P['returnUrl'], $request)); } // Redirecting to FormEngine with instructions to create a new record // AND when closing to return back with information about that records ID etc. $normalizedParams = $request->getAttribute('normalizedParams'); $redirectUrl = (string)$this->uriBuilder->buildUriFromRoute('record_edit', [ 'returnEditConf' => 1, 'edit[' . $this->P['params']['table'] . '][' . $this->pid . ']' => 'new', // @todo add module context to wizard/add routes and set module context here 'returnUrl' => $normalizedParams->getRequestUri(), ]); return new RedirectResponse($redirectUrl); } /** * Initialization of the class. */ protected function init(ServerRequestInterface $request): void { $parsedBody = $request->getParsedBody(); $queryParams = $request->getQueryParams(); // Init GPvars: $this->P = $parsedBody['P'] ?? $queryParams['P'] ?? []; $this->returnEditConf = $parsedBody['returnEditConf'] ?? $queryParams['returnEditConf'] ?? ''; // Get this record $record = BackendUtility::getRecord($this->P['table'], $this->P['uid']); // Set table: $this->table = $this->P['params']['table']; // Get TSconfig for it. $TSconfig = FormEngineUtility::getTCEFORM_TSconfig( $this->P['table'], is_array($record) ? $record : ['pid' => (int)$this->P['params']['pid']] ); // Set [params][pid] if (str_starts_with($this->P['params']['pid'], '###') && str_ends_with($this->P['params']['pid'], '###')) { $keyword = substr($this->P['params']['pid'], 3, -3); $this->pid = str_starts_with($keyword, 'PAGE_TSCONFIG_') ? (int)$TSconfig[$this->P['field']][$keyword] : (int)$TSconfig['_' . $keyword]; } else { $this->pid = (int)$this->P['params']['pid']; } // If a new id has returned from a newly created record... if ($this->returnEditConf) { $editConfiguration = json_decode($this->returnEditConf, true); if (is_array($editConfiguration[$this->table]) && MathUtility::canBeInterpretedAsInteger($this->P['uid'])) { // Getting id and cmd from returning editConf array. reset($editConfiguration[$this->table]); $this->id = (int)key($editConfiguration[$this->table]); $cmd = current($editConfiguration[$this->table]); // ... and if everything seems OK we will register some classes for inclusion and instruct the object // to perform processing later. if ($this->P['params']['setValue'] && $cmd === 'edit' && $this->id && $this->P['table'] && $this->P['field'] && $this->P['uid'] ) { $liveRecord = BackendUtility::getLiveVersionOfRecord($this->table, $this->id, 'uid'); if ($liveRecord) { $this->id = $liveRecord['uid']; } $this->processDataFlag = 1; } } } } }