inlineData = $this->data['inlineData']; $inlineStructure = $this->data['inlineStructure']; $row = $this->data['databaseRow']; $parameterArray = $this->data['parameterArray']; $config = $parameterArray['fieldConf']['config']; $resultArray = $this->initializeResultArray(); // Add the current inline job to the structure stack $inlineStructure['stable'][] = [ 'table' => $this->data['tableName'], 'uid' => $row['uid'], 'field' => $this->data['fieldName'], 'config' => $config, ]; // Hand over original returnUrl to SiteInlineAjaxController. Needed if opening for instance a // nested element in a new view to then go back to the original returnUrl and not the url of // the site inline ajax controller. $config['originalReturnUrl'] = $this->data['returnUrl']; // e.g. data[site][1][languages] $nameForm = $this->inlineStackProcessor->getFormPrefixFromStructure($inlineStructure); // e.g. data-0-site-1-languages $nameObject = $this->inlineStackProcessor->getDomObjectIdPrefixFromStructure($inlineStructure, $this->data['inlineFirstPid']); // e.g. array('table' => 'site', 'uid' => '1', 'field' => 'languages', 'config' => array()) $top = $this->inlineStackProcessor->getStructureLevelFromStructure($inlineStructure, 0); $this->inlineData['config'][$nameObject] = [ 'table' => self::FOREIGN_TABLE, ]; $configJson = (string)json_encode($config); $this->inlineData['config'][$nameObject . '-' . self::FOREIGN_TABLE] = [ 'min' => $config['minitems'], 'max' => $config['maxitems'], 'sortable' => false, 'top' => [ 'table' => $top['table'], 'uid' => $top['uid'], ], 'context' => [ 'config' => $configJson, 'hmac' => $this->hashService->hmac($configJson, 'InlineContext'), ], ]; $this->inlineData['nested'][$nameObject] = $this->data['tabAndInlineStack']; $uniqueIds = []; foreach ($parameterArray['fieldConf']['children'] as $children) { $value = (int)($children['databaseRow'][self::FOREIGN_FIELD]['0'] ?? 0); if (isset($children['databaseRow']['uid'])) { $uniqueIds[$children['databaseRow']['uid']] = $value; } } $uniquePossibleRecords = $config['uniquePossibleRecords'] ?? []; $possibleRecordsUidToTitle = []; foreach ($uniquePossibleRecords as $possibleRecord) { $possibleRecordsUidToTitle[$possibleRecord['value']] = $possibleRecord['label']; } $this->inlineData['unique'][$nameObject . '-' . self::FOREIGN_TABLE] = [ // Usually "max" would be the number of possible records. However, since // we also allow new languages to be created, we just use the maxitems value. 'max' => $config['maxitems'], // "used" must be a string array 'used' => array_map(strval(...), $uniqueIds), 'table' => self::FOREIGN_TABLE, 'elTable' => self::FOREIGN_TABLE, 'field' => self::FOREIGN_FIELD, 'possible' => $possibleRecordsUidToTitle, ]; $resultArray['inlineData'] = $this->inlineData; $fieldInformationResult = $this->renderFieldInformation(); $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldInformationResult, false); $selectorOptions = $childRecordUids = $childHtml = []; foreach ($config['uniquePossibleRecords'] ?? [] as $record) { // Do not add the PHP_INT_MAX placeholder or already configured languages if ($record['value'] !== PHP_INT_MAX && !in_array($record['value'], $uniqueIds, true)) { $selectorOptions[] = ['value' => (string)$record['value'], 'label' => (string)$record['label']]; } } foreach ($this->data['parameterArray']['fieldConf']['children'] as $children) { $children['inlineParentUid'] = $row['uid']; $children['inlineFirstPid'] = $this->data['inlineFirstPid']; $children['inlineParentConfig'] = $config; $children['inlineData'] = $this->inlineData; $children['inlineStructure'] = $inlineStructure; $children['inlineExpandCollapseStateArray'] = $this->data['inlineExpandCollapseStateArray']; $children['renderType'] = 'inlineRecordContainer'; $childResult = $this->nodeFactory->create($children)->render(); $childHtml[] = $childResult['html']; $resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $childResult, false); if (isset($children['databaseRow']['uid'])) { $childRecordUids[] = $children['databaseRow']['uid']; } } $view = $this->backendViewFactory->create($this->data['request']); $view->assignMultiple([ 'nameObject' => $nameObject, 'nameForm' => $nameForm, 'webComponentAttributes' => GeneralUtility::implodeAttributes([ 'id' => $nameObject, 'data-type' => 'language', 'data-object-group' => $nameObject . '-' . self::FOREIGN_TABLE, 'data-form-field' => $nameForm, 'data-expand-single' => (bool)($config['appearance']['expandSingle'] ?? false) ? 'true' : 'false', 'data-sortable' => 'false', 'data-min' => (int)($config['minitems'] ?? 0), 'data-max' => (int)($config['maxitems'] ?? 0), ], true), 'fieldInformation' => $fieldInformationResult['html'], 'selectorConfiguration' => [ 'identifier' => $nameObject . '-' . self::FOREIGN_TABLE . '_selector', 'options' => $selectorOptions, ], 'inlineRecords' => [ 'identifier' => $nameObject . '_records', 'title' => trim($parameterArray['fieldConf']['label'] ?? ''), 'records' => implode(PHP_EOL, $childHtml), ], 'childRecordUids' => implode(',', $childRecordUids), 'validationRules' => $this->getValidationDataAsJsonString([ 'type' => 'inline', 'minitems' => $config['minitems'] ?? null, 'maxitems' => $config['maxitems'] ?? null, ]), 'presetOptions' => [ 'identifier' => $nameObject . '_preset', 'options' => $this->siteLanguagePresets->getAllForSelector(), ], ]); $resultArray['html'] = $this->wrapWithFieldsetAndLegend($view->render('Form/SiteLanguageContainer')); $resultArray['javaScriptModules'][] = JavaScriptModuleInstruction::create('@typo3/backend/form-engine/container/inline-control-container.js'); return $resultArray; } }