TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
<?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\Core\Schema;
|
||||
|
||||
use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidDataStructureException;
|
||||
use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidIdentifierException;
|
||||
use TYPO3\CMS\Core\Configuration\FlexForm\Exception\InvalidTcaSchemaException;
|
||||
use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
|
||||
|
||||
/**
|
||||
* Low-level API to parse TCA to find field types which should be processed, as they contain
|
||||
* a relation.
|
||||
*
|
||||
* This also parses ALL flexforms available, that's why it juggles through all FlexForm
|
||||
* fields and parses the FlexForms as well.
|
||||
*
|
||||
* Everything is stored in a simple "RelationMap" object with an internal array structure.
|
||||
*
|
||||
* @internal not part of TYPO3 API as it should not be exposed, although this is really cool and powerful.
|
||||
*/
|
||||
final readonly class RelationMapBuilder
|
||||
{
|
||||
public function __construct(
|
||||
private FlexFormTools $flexFormTools
|
||||
) {}
|
||||
|
||||
public function buildFromStructure(array $tca): RelationMap
|
||||
{
|
||||
$relationMap = new RelationMap();
|
||||
foreach ($tca as $table => $tableConfig) {
|
||||
// What fields can have a relational connection to other tables?
|
||||
foreach ($tableConfig['columns'] ?? [] as $fieldName => $fieldConfig) {
|
||||
$fieldConfig = $fieldConfig['config'] ?? null;
|
||||
if (!in_array($fieldConfig['type'] ?? '', ['select', 'group', 'inline', 'file', 'category', 'flex'], true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($fieldConfig['type'] === 'flex') {
|
||||
$this->addRelationsForFlexFieldToRelationMap($table, $tableConfig, $fieldName, $relationMap);
|
||||
} else {
|
||||
$relationMap->add($table, $fieldName, $fieldConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $relationMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds relations for a flex field to the relation map.
|
||||
* Note: Inside a section, it is not possible to add a field with a relation (type 'inline', 'file', 'folder', 'group', 'category').
|
||||
* See TcaFlexProcess class for details.
|
||||
*/
|
||||
private function addRelationsForFlexFieldToRelationMap(string $tableName, array $tableConfig, string $fieldName, RelationMap $relationMap): void
|
||||
{
|
||||
foreach (array_merge(['default'], array_keys($tableConfig['types'] ?? [])) as $recordType) {
|
||||
try {
|
||||
$dataStructure = $this->flexFormTools->parseDataStructureByIdentifier(json_encode([
|
||||
'type' => 'tca',
|
||||
'tableName' => $tableName,
|
||||
'fieldName' => $fieldName,
|
||||
'dataStructureKey' => $recordType,
|
||||
]), $tableConfig);
|
||||
} catch (InvalidTcaSchemaException|InvalidIdentifierException|InvalidDataStructureException) {
|
||||
// Skip default on error
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!is_array($dataStructure['sheets'] ?? null)) {
|
||||
continue;
|
||||
}
|
||||
foreach ($dataStructure['sheets'] as $sheetIdentifier => $sheet) {
|
||||
foreach ($sheet['ROOT']['el'] as $flexFieldName => $flexFieldConfig) {
|
||||
$fieldIdentifier = $sheetIdentifier . '/' . $flexFieldName;
|
||||
$relationMap->add($tableName, $fieldName, $flexFieldConfig['config'] ?? [], $fieldIdentifier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user