| Current Path : /var/www/surf/TYPO3/vendor/typo3/cms-backend/Classes/Controller/ |
| Current File : /var/www/surf/TYPO3/vendor/typo3/cms-backend/Classes/Controller/FormSelectTreeAjaxController.php |
<?php
declare(strict_types=1);
/*
* This file is part of the TYPO3 CMS project.
*
* It is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License, either version 2
* of the License, or any later version.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* The TYPO3 project - inspiring people to share!
*/
namespace TYPO3\CMS\Backend\Controller;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Backend\Form\FormDataCompiler;
use TYPO3\CMS\Backend\Form\FormDataGroup\TcaSelectTreeAjaxFieldData;
use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
use TYPO3\CMS\Core\Http\JsonResponse;
use TYPO3\CMS\Core\Utility\GeneralUtility;
/**
* Backend controller for selectTree ajax operations
*/
class FormSelectTreeAjaxController
{
/**
* Returns json representing category tree
*
* @throws \RuntimeException
*/
public function fetchDataAction(ServerRequestInterface $request): ResponseInterface
{
$tableName = $request->getQueryParams()['tableName'] ?? '';
$fieldName = $request->getQueryParams()['fieldName'] ?? '';
// Prepare processedTca: Remove all column definitions except the one that contains
// our tree definition. This way only this field is calculated, everything else is ignored.
if (!isset($GLOBALS['TCA'][$tableName]) || !is_array($GLOBALS['TCA'][$tableName])) {
throw new \RuntimeException(
'TCA for table ' . $tableName . ' not found',
1479386729
);
}
$processedTca = $GLOBALS['TCA'][$tableName];
if (!isset($processedTca['columns'][$fieldName]) || !is_array($processedTca['columns'][$fieldName])) {
throw new \RuntimeException(
'TCA for table ' . $tableName . ' and field ' . $fieldName . ' not found',
1479386990
);
}
// Force given record type and set showitem to our field only
$recordTypeValue = $request->getQueryParams()['recordTypeValue'];
$processedTca['types'][$recordTypeValue]['showitem'] = $fieldName;
// Unset all columns except our field
$processedTca['columns'] = [
$fieldName => $processedTca['columns'][$fieldName],
];
$dataStructureIdentifier = '';
$flexFormSheetName = '';
$flexFormFieldName = '';
$flexFormContainerIdentifier = '';
$flexFormContainerFieldName = '';
$flexSectionContainerPreparation = [];
if ($processedTca['columns'][$fieldName]['config']['type'] === 'flex') {
if (!empty($request->getQueryParams()['dataStructureIdentifier'])) {
$dataStructureIdentifier = $request->getQueryParams()['dataStructureIdentifier'];
}
$flexFormSheetName = $request->getQueryParams()['flexFormSheetName'];
$flexFormFieldName = $request->getQueryParams()['flexFormFieldName'];
$flexFormContainerName = $request->getQueryParams()['flexFormContainerName'];
$flexFormContainerIdentifier = $request->getQueryParams()['flexFormContainerIdentifier'];
$flexFormContainerFieldName = $request->getQueryParams()['flexFormContainerFieldName'];
$flexFormSectionContainerIsNew = (bool)$request->getQueryParams()['flexFormSectionContainerIsNew'];
$flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
$dataStructure = $flexFormTools->parseDataStructureByIdentifier($dataStructureIdentifier);
// Reduce given data structure down to the relevant element only
if (empty($flexFormContainerFieldName)) {
if (isset($dataStructure['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName])
) {
$dataStructure = [
'sheets' => [
$flexFormSheetName => [
'ROOT' => [
'type' => 'array',
'el' => [
$flexFormFieldName => $dataStructure['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName],
],
],
],
],
];
}
} elseif (isset($dataStructure['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName]
['el'][$flexFormContainerName]
['el'][$flexFormContainerFieldName])
) {
// If this is a tree in a section container that has just been added by the FlexFormAjaxController
// "new container" action, then this container is not yet persisted, so we need to trigger the
// TcaFlexProcess data provider again to prepare the DS and databaseRow of that container.
if ($flexFormSectionContainerIsNew) {
$flexSectionContainerPreparation = [
'flexFormSheetName' => $flexFormSheetName,
'flexFormFieldName' => $flexFormFieldName,
'flexFormContainerName' => $flexFormContainerName,
'flexFormContainerIdentifier' => $flexFormContainerIdentifier,
];
}
// Now restrict the data structure to our tree element only
$dataStructure = [
'sheets' => [
$flexFormSheetName => [
'ROOT' => [
'type' => 'array',
'el' => [
$flexFormFieldName => [
'section' => 1,
'type' => 'array',
'el' => [
$flexFormContainerName => [
'type' => 'array',
'el' => [
$flexFormContainerFieldName => $dataStructure['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName]
['el'][$flexFormContainerName]
['el'][$flexFormContainerFieldName],
],
],
],
],
],
],
],
],
];
}
$processedTca['columns'][$fieldName]['config']['ds'] = $dataStructure;
$processedTca['columns'][$fieldName]['config']['dataStructureIdentifier'] = $dataStructureIdentifier;
}
$formDataCompiler = GeneralUtility::makeInstance(FormDataCompiler::class);
$formDataCompilerInput = [
'request' => $request,
'tableName' => $tableName,
'vanillaUid' => (int)$request->getQueryParams()['uid'],
'command' => $request->getQueryParams()['command'],
'processedTca' => $processedTca,
'recordTypeValue' => $recordTypeValue,
'selectTreeCompileItems' => true,
'flexSectionContainerPreparation' => $flexSectionContainerPreparation,
];
if (!empty($request->getQueryParams()['overrideValues'])) {
$formDataCompilerInput['overrideValues'] = json_decode($request->getQueryParams()['overrideValues'], true);
}
if (!empty($request->getQueryParams()['defaultValues'])) {
$formDataCompilerInput['defaultValues'] = json_decode($request->getQueryParams()['defaultValues'], true);
}
$formData = $formDataCompiler->compile($formDataCompilerInput, GeneralUtility::makeInstance(TcaSelectTreeAjaxFieldData::class));
if ($formData['processedTca']['columns'][$fieldName]['config']['type'] === 'flex') {
if (empty($flexFormContainerFieldName)) {
$treeData = $formData['processedTca']['columns'][$fieldName]['config']['ds']
['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName]['config']['items'];
} else {
$treeData = $formData['processedTca']['columns'][$fieldName]['config']['ds']
['sheets'][$flexFormSheetName]['ROOT']
['el'][$flexFormFieldName]
['children'][$flexFormContainerIdentifier]
['el'][$flexFormContainerFieldName]['config']['items'];
}
} else {
$treeData = $formData['processedTca']['columns'][$fieldName]['config']['items'];
}
return new JsonResponse($treeData ?? []);
}
}