TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:09 +02:00
commit af8cc155b5
6818 changed files with 642608 additions and 0 deletions
+143
View File
@@ -0,0 +1,143 @@
<?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\Schema\Field\FieldCollection;
use TYPO3\CMS\Core\Schema\Field\FieldTypeInterface;
use TYPO3\CMS\Core\Schema\Struct\FlexSheet;
final readonly class FlexFormSchema implements SchemaInterface
{
public function __construct(
private string $structIdentifier,
/** @var FlexSheet[] */
private array $sheets
) {}
public function getSheets(): array
{
return $this->sheets;
}
public function getFields(?callable $filterFunction = null): FieldCollection
{
$allFields = [];
foreach ($this->sheets as $sheet) {
$allFields = array_merge($allFields, iterator_to_array($sheet->getFields()));
}
if ($filterFunction === null) {
return new FieldCollection($allFields);
}
return new FieldCollection(array_filter(iterator_to_array($allFields), $filterFunction));
}
public function getName(): string
{
return $this->structIdentifier;
}
public function getField(string $fieldName, ?string $sheetName = null): ?FieldTypeInterface
{
if ($sheetName !== null) {
return $this->getFieldFromSheet($sheetName, $fieldName);
}
foreach ($this->sheets as $name => $sheet) {
if ($field = $this->getFieldFromSheet($name, $fieldName)) {
return $field;
}
}
return null;
}
public static function __set_state(array $state): self
{
return new self(...$state);
}
/**
* This method attempts to find a field within a given sheet.
*
* If the field is not set directly on the sheet, each section
* of the sheet will be checked for a matching field.
*/
private function getFieldFromSheet(string $sheetName, string $fieldName): ?FieldTypeInterface
{
if (!isset($this->sheets[$sheetName])) {
return null;
}
$sheet = $this->sheets[$sheetName];
if ($sheet->hasField($sheetName . '/' . $fieldName)) {
return $sheet->getField($sheetName . '/' . $fieldName);
}
return $this->getFieldFromSections($sheetName, $fieldName);
}
/**
* This method searches for a field name within all sections of a sheet.
*
* Any slashes in the field name, section name, or container name
* are replaced with dots to support field names such as:
* - settings.mysettings.67fb88e136a4a575936...
* - my_settings.67fb88e136a4a575936...
*/
private function getFieldFromSections(string $sheetName, string $fieldName): ?FieldTypeInterface
{
$sheet = $this->sheets[$sheetName];
$fieldPath = $sheetName . '.' . $fieldName;
foreach ($sheet->getSections() as $sectionName => $section) {
$sectionPath = str_replace('/', '.', $sectionName);
// If the field is not inside the current section, continue to the next
if (!str_starts_with($fieldPath, $sectionPath)) {
continue;
}
// Remove the section path from the field name
$relativeField = substr($fieldPath, strlen($sectionPath) + 1);
if (($pos = strpos($relativeField, '.')) !== false) {
// Get the container name from the field
$containerField = substr($relativeField, $pos + 1);
foreach ($section as $containerName => $container) {
// If the field is not inside the current container, continue to the next
if (!str_starts_with($sectionName . '/' . $containerField, $containerName)) {
continue;
}
// Get the field name
$finalFieldName = substr($sectionName . '/' . $containerField, strlen($containerName) + 1);
/** @var \TYPO3\CMS\Core\Schema\Struct\FlexSectionContainer $container */
if ($container->hasField($finalFieldName)) {
return $container->getField($finalFieldName);
}
}
}
}
return null;
}
}