From 235c1c974eb155328ae58d45947f41abeb568cf9 Mon Sep 17 00:00:00 2001 From: Oliver Bartsch <bo@cedev.de> Date: Tue, 27 Aug 2024 11:16:35 +0200 Subject: [PATCH] [TASK] Clean up TcaSchema field types Clean up of field types for TcaSchema. In detail: * Removes duplicate interface implementation * Move __set_state() to abstract * Introduces FieldFormat enum * Extends some FieldType's for convenience methods * Extends TcaSchema::getFields() to support list of fields * Adds styleguide example for type=none with format configuration Resolves: #104741 Releases: main Change-Id: I06afc6d52eb0f5fa299ffef5701f178378f7c942 Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/85786 Tested-by: core-ci <typo3@b13.com> Tested-by: Jochen Roth <rothjochen@gmail.com> Tested-by: Benjamin Kott <benjamin.kott@outlook.com> Reviewed-by: Jochen Roth <rothjochen@gmail.com> Tested-by: Oliver Bartsch <bo@cedev.de> Reviewed-by: Benjamin Kott <benjamin.kott@outlook.com> Reviewed-by: Oliver Bartsch <bo@cedev.de> --- .../Schema/Field/AbstractFieldType.php | 6 + .../Schema/Field/CategoryFieldType.php | 14 +-- .../Schema/Field/CheckboxFieldType.php | 7 +- .../Classes/Schema/Field/ColorFieldType.php | 7 +- .../Schema/Field/DateTimeFieldType.php | 12 +- .../Classes/Schema/Field/EmailFieldType.php | 7 +- .../Classes/Schema/Field/FieldCollection.php | 10 +- .../Classes/Schema/Field/FileFieldType.php | 22 +++- .../Schema/Field/FlexFormFieldType.php | 11 +- .../Classes/Schema/Field/FolderFieldType.php | 7 +- .../Classes/Schema/Field/GroupFieldType.php | 7 +- .../Field/ImageManipulationFieldType.php | 7 +- .../Classes/Schema/Field/InlineFieldType.php | 9 +- .../Classes/Schema/Field/InputFieldType.php | 7 +- .../Classes/Schema/Field/JsonFieldType.php | 7 +- .../Schema/Field/LanguageFieldType.php | 7 +- .../Classes/Schema/Field/LinkFieldType.php | 7 +- .../Classes/Schema/Field/NoneFieldType.php | 8 +- .../Classes/Schema/Field/NumberFieldType.php | 7 +- .../Schema/Field/PassthroughFieldType.php | 7 +- .../Schema/Field/PasswordFieldType.php | 7 +- .../Classes/Schema/Field/RadioFieldType.php | 7 +- .../Schema/Field/SelectRelationFieldType.php | 7 +- .../Classes/Schema/Field/SlugFieldType.php | 11 +- .../Schema/Field/StaticSelectFieldType.php | 14 ++- .../Classes/Schema/Field/TextFieldType.php | 7 +- .../Classes/Schema/Field/UserFieldType.php | 6 +- .../Classes/Schema/Field/UuidFieldType.php | 6 +- .../core/Classes/Schema/FieldFormat.php | 112 ++++++++++++++++++ .../sysext/core/Classes/Schema/TcaSchema.php | 10 +- .../TCA/tx_styleguide_elements_basic.php | 14 ++- typo3/sysext/styleguide/ext_tables.sql | 1 + 32 files changed, 220 insertions(+), 158 deletions(-) create mode 100644 typo3/sysext/core/Classes/Schema/FieldFormat.php diff --git a/typo3/sysext/core/Classes/Schema/Field/AbstractFieldType.php b/typo3/sysext/core/Classes/Schema/Field/AbstractFieldType.php index ed7a1fa3371d..b8fe411e6403 100644 --- a/typo3/sysext/core/Classes/Schema/Field/AbstractFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/AbstractFieldType.php @@ -29,6 +29,12 @@ abstract readonly class AbstractFieldType implements FieldTypeInterface protected array $configuration, ) {} + public static function __set_state(array $state): self + { + /** @phpstan-ignore-next-line Usage is safe because state is exported by PHP var_export() from the static instance */ + return new static(...$state); + } + abstract public function getType(): string; public function getName(): string diff --git a/typo3/sysext/core/Classes/Schema/Field/CategoryFieldType.php b/typo3/sysext/core/Classes/Schema/Field/CategoryFieldType.php index 59da0b647d6e..fb0f7feec554 100644 --- a/typo3/sysext/core/Classes/Schema/Field/CategoryFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/CategoryFieldType.php @@ -22,12 +22,12 @@ use TYPO3\CMS\Core\Schema\RelationshipType; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class CategoryFieldType extends AbstractFieldType implements FieldTypeInterface, RelationalFieldTypeInterface +final readonly class CategoryFieldType extends AbstractFieldType implements RelationalFieldTypeInterface { public function __construct( protected string $name, protected array $configuration, - protected array $relations, + protected array $relations ) {} public function getType(): string @@ -35,6 +35,11 @@ final readonly class CategoryFieldType extends AbstractFieldType implements Fiel return 'category'; } + public function getTreeConfiguration(): array + { + return $this->configuration['treeConfig'] ?? []; + } + public function getRelations(): array { return $this->relations; @@ -44,9 +49,4 @@ final readonly class CategoryFieldType extends AbstractFieldType implements Fiel { return RelationshipType::fromTcaConfiguration($this->configuration); } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/CheckboxFieldType.php b/typo3/sysext/core/Classes/Schema/Field/CheckboxFieldType.php index 423aeca59ba2..6b83056a7507 100644 --- a/typo3/sysext/core/Classes/Schema/Field/CheckboxFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/CheckboxFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class CheckboxFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class CheckboxFieldType extends AbstractFieldType { public function getType(): string { return 'check'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/ColorFieldType.php b/typo3/sysext/core/Classes/Schema/Field/ColorFieldType.php index 335fe8342d9f..eafb6c7c7df7 100644 --- a/typo3/sysext/core/Classes/Schema/Field/ColorFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/ColorFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class ColorFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class ColorFieldType extends AbstractFieldType { public function getType(): string { return 'color'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/DateTimeFieldType.php b/typo3/sysext/core/Classes/Schema/Field/DateTimeFieldType.php index 18e1824b83c1..b46459799f96 100644 --- a/typo3/sysext/core/Classes/Schema/Field/DateTimeFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/DateTimeFieldType.php @@ -22,7 +22,7 @@ use TYPO3\CMS\Core\Database\Query\QueryHelper; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class DateTimeFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class DateTimeFieldType extends AbstractFieldType { public function getType(): string { @@ -38,14 +38,4 @@ final readonly class DateTimeFieldType extends AbstractFieldType implements Fiel { return in_array($this->configuration['dbType'] ?? null, QueryHelper::getDateTimeTypes(), true) ? $this->configuration['dbType'] : null; } - - public function isNullable(): bool - { - return (bool)($this->configuration['nullable'] ?? false); - } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/EmailFieldType.php b/typo3/sysext/core/Classes/Schema/Field/EmailFieldType.php index 9012ea0616d5..413f14517c48 100644 --- a/typo3/sysext/core/Classes/Schema/Field/EmailFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/EmailFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class EmailFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class EmailFieldType extends AbstractFieldType { public function getType(): string { return 'email'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/FieldCollection.php b/typo3/sysext/core/Classes/Schema/Field/FieldCollection.php index e462968130ae..1f7fabfa342b 100644 --- a/typo3/sysext/core/Classes/Schema/Field/FieldCollection.php +++ b/typo3/sysext/core/Classes/Schema/Field/FieldCollection.php @@ -29,6 +29,11 @@ final readonly class FieldCollection implements \ArrayAccess, \IteratorAggregate protected array $fieldDefinitions = [] ) {} + public static function __set_state(array $state): self + { + return new self(...$state); + } + public function offsetExists(mixed $offset): bool { return isset($this->fieldDefinitions[$offset]); @@ -61,9 +66,4 @@ final readonly class FieldCollection implements \ArrayAccess, \IteratorAggregate { return count($this->fieldDefinitions); } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/FileFieldType.php b/typo3/sysext/core/Classes/Schema/Field/FileFieldType.php index 15449a705506..d4e2973f3b14 100644 --- a/typo3/sysext/core/Classes/Schema/Field/FileFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/FileFieldType.php @@ -18,6 +18,7 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Schema\Field; use TYPO3\CMS\Core\Schema\RelationshipType; +use TYPO3\CMS\Core\Utility\GeneralUtility; /** * This is a field to a "file" (which is very similar to "inline") but with a hard-coded @@ -25,7 +26,7 @@ use TYPO3\CMS\Core\Schema\RelationshipType; * * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class FileFieldType extends AbstractFieldType implements FieldTypeInterface, RelationalFieldTypeInterface +final readonly class FileFieldType extends AbstractFieldType implements RelationalFieldTypeInterface { public function __construct( protected string $name, @@ -38,6 +39,20 @@ final readonly class FileFieldType extends AbstractFieldType implements FieldTyp return 'file'; } + public function getAllowedFileExtensions(): array + { + return is_array($this->configuration['allowed'] ?? null) + ? $this->configuration['allowed'] + : GeneralUtility::trimExplode(',', $this->configuration['allowed'] ?? '', true); + } + + public function getDisallowedFileExtensions(): array + { + return is_array($this->configuration['disallowed'] ?? null) + ? $this->configuration['disallowed'] + : GeneralUtility::trimExplode(',', $this->configuration['disallowed'] ?? '', true); + } + public function getRelations(): array { return $this->relations; @@ -47,9 +62,4 @@ final readonly class FileFieldType extends AbstractFieldType implements FieldTyp { return RelationshipType::fromTcaConfiguration($this->configuration); } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/FlexFormFieldType.php b/typo3/sysext/core/Classes/Schema/Field/FlexFormFieldType.php index 0f9452fe0f3e..e16c068bc7ec 100644 --- a/typo3/sysext/core/Classes/Schema/Field/FlexFormFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/FlexFormFieldType.php @@ -20,20 +20,15 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class FlexFormFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class FlexFormFieldType extends AbstractFieldType { - public function __construct( - protected string $name, - protected array $configuration, - ) {} - public function getType(): string { return 'flex'; } - public static function __set_state(array $state): self + public function getDataStructure(): array { - return new self(...$state); + return is_array($this->configuration['ds'] ?? null) ? $this->configuration['ds'] : []; } } diff --git a/typo3/sysext/core/Classes/Schema/Field/FolderFieldType.php b/typo3/sysext/core/Classes/Schema/Field/FolderFieldType.php index 9c39e454800e..c9248594db89 100644 --- a/typo3/sysext/core/Classes/Schema/Field/FolderFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/FolderFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class FolderFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class FolderFieldType extends AbstractFieldType { public function getType(): string { return 'folder'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/GroupFieldType.php b/typo3/sysext/core/Classes/Schema/Field/GroupFieldType.php index e6ffa69fac06..c46d4d25b450 100644 --- a/typo3/sysext/core/Classes/Schema/Field/GroupFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/GroupFieldType.php @@ -22,7 +22,7 @@ use TYPO3\CMS\Core\Schema\RelationshipType; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class GroupFieldType extends AbstractFieldType implements FieldTypeInterface, RelationalFieldTypeInterface +final readonly class GroupFieldType extends AbstractFieldType implements RelationalFieldTypeInterface { public function __construct( protected string $name, @@ -44,9 +44,4 @@ final readonly class GroupFieldType extends AbstractFieldType implements FieldTy { return RelationshipType::fromTcaConfiguration($this->configuration); } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/ImageManipulationFieldType.php b/typo3/sysext/core/Classes/Schema/Field/ImageManipulationFieldType.php index 31da630864b6..a003e285bb58 100644 --- a/typo3/sysext/core/Classes/Schema/Field/ImageManipulationFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/ImageManipulationFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class ImageManipulationFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class ImageManipulationFieldType extends AbstractFieldType { public function getType(): string { return 'imageManipulation'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/InlineFieldType.php b/typo3/sysext/core/Classes/Schema/Field/InlineFieldType.php index f36021e54385..140a4a1aea80 100644 --- a/typo3/sysext/core/Classes/Schema/Field/InlineFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/InlineFieldType.php @@ -24,12 +24,12 @@ use TYPO3\CMS\Core\Schema\RelationshipType; * * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class InlineFieldType extends AbstractFieldType implements FieldTypeInterface, RelationalFieldTypeInterface +final readonly class InlineFieldType extends AbstractFieldType implements RelationalFieldTypeInterface { public function __construct( protected string $name, protected array $configuration, - protected array $relations, + protected array $relations ) {} public function getType(): string @@ -51,9 +51,4 @@ final readonly class InlineFieldType extends AbstractFieldType implements FieldT { return (bool)($this->configuration['behaviour']['disableMovingChildrenWithParent'] ?? false) === false; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/InputFieldType.php b/typo3/sysext/core/Classes/Schema/Field/InputFieldType.php index 1f252b89f37d..c00516a39a32 100644 --- a/typo3/sysext/core/Classes/Schema/Field/InputFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/InputFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class InputFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class InputFieldType extends AbstractFieldType { public function getType(): string { return 'input'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/JsonFieldType.php b/typo3/sysext/core/Classes/Schema/Field/JsonFieldType.php index 72a4a1b5ed59..815f9ae3bda9 100644 --- a/typo3/sysext/core/Classes/Schema/Field/JsonFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/JsonFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class JsonFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class JsonFieldType extends AbstractFieldType { public function getType(): string { return 'json'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/LanguageFieldType.php b/typo3/sysext/core/Classes/Schema/Field/LanguageFieldType.php index 5b695b2f739f..ba0d524f0ad7 100644 --- a/typo3/sysext/core/Classes/Schema/Field/LanguageFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/LanguageFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class LanguageFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class LanguageFieldType extends AbstractFieldType { public function getType(): string { return 'language'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/LinkFieldType.php b/typo3/sysext/core/Classes/Schema/Field/LinkFieldType.php index 206221914252..d42a8a8615c1 100644 --- a/typo3/sysext/core/Classes/Schema/Field/LinkFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/LinkFieldType.php @@ -20,7 +20,7 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class LinkFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class LinkFieldType extends AbstractFieldType { public function getType(): string { @@ -31,9 +31,4 @@ final readonly class LinkFieldType extends AbstractFieldType implements FieldTyp { return $this->configuration['allowedTypes'] ?? ['*']; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/NoneFieldType.php b/typo3/sysext/core/Classes/Schema/Field/NoneFieldType.php index a64783c5e21d..caf5283bfd8f 100644 --- a/typo3/sysext/core/Classes/Schema/Field/NoneFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/NoneFieldType.php @@ -17,18 +17,20 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Schema\Field; +use TYPO3\CMS\Core\Schema\FieldFormat; + /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class NoneFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class NoneFieldType extends AbstractFieldType { public function getType(): string { return 'none'; } - public static function __set_state(array $state): self + public function getFormat(): FieldFormat { - return new self(...$state); + return FieldFormat::fromTcaConfiguration($this->configuration); } } diff --git a/typo3/sysext/core/Classes/Schema/Field/NumberFieldType.php b/typo3/sysext/core/Classes/Schema/Field/NumberFieldType.php index d41866864e39..051bf8263f6c 100644 --- a/typo3/sysext/core/Classes/Schema/Field/NumberFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/NumberFieldType.php @@ -20,7 +20,7 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class NumberFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class NumberFieldType extends AbstractFieldType { public function getType(): string { @@ -31,9 +31,4 @@ final readonly class NumberFieldType extends AbstractFieldType implements FieldT { return $this->configuration['format'] ?? ''; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/PassthroughFieldType.php b/typo3/sysext/core/Classes/Schema/Field/PassthroughFieldType.php index e309344375be..ddbad6ee82b1 100644 --- a/typo3/sysext/core/Classes/Schema/Field/PassthroughFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/PassthroughFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class PassthroughFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class PassthroughFieldType extends AbstractFieldType { public function getType(): string { return 'passthrough'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/PasswordFieldType.php b/typo3/sysext/core/Classes/Schema/Field/PasswordFieldType.php index 318b654ae675..85c5fdf9c470 100644 --- a/typo3/sysext/core/Classes/Schema/Field/PasswordFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/PasswordFieldType.php @@ -20,7 +20,7 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class PasswordFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class PasswordFieldType extends AbstractFieldType { public function getType(): string { @@ -31,9 +31,4 @@ final readonly class PasswordFieldType extends AbstractFieldType implements Fiel { return $this->configuration['hashed'] ?? true; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/RadioFieldType.php b/typo3/sysext/core/Classes/Schema/Field/RadioFieldType.php index 32b63d576d08..ec39a06d501d 100644 --- a/typo3/sysext/core/Classes/Schema/Field/RadioFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/RadioFieldType.php @@ -20,15 +20,10 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class RadioFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class RadioFieldType extends AbstractFieldType { public function getType(): string { return 'radio'; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/SelectRelationFieldType.php b/typo3/sysext/core/Classes/Schema/Field/SelectRelationFieldType.php index d43dd66cba2a..c633af078398 100644 --- a/typo3/sysext/core/Classes/Schema/Field/SelectRelationFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/SelectRelationFieldType.php @@ -24,7 +24,7 @@ use TYPO3\CMS\Core\Schema\RelationshipType; * * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class SelectRelationFieldType extends AbstractFieldType implements FieldTypeInterface, RelationalFieldTypeInterface +final readonly class SelectRelationFieldType extends AbstractFieldType implements RelationalFieldTypeInterface { public function __construct( protected string $name, @@ -46,9 +46,4 @@ final readonly class SelectRelationFieldType extends AbstractFieldType implement { return RelationshipType::fromTcaConfiguration($this->configuration); } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/SlugFieldType.php b/typo3/sysext/core/Classes/Schema/Field/SlugFieldType.php index e2998a99b8cf..0cb5c678b9c4 100644 --- a/typo3/sysext/core/Classes/Schema/Field/SlugFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/SlugFieldType.php @@ -20,15 +20,20 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class SlugFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class SlugFieldType extends AbstractFieldType { public function getType(): string { return 'slug'; } - public static function __set_state(array $state): self + public function getGeneratorOption(string $optionName): array|string|bool|null { - return new self(...$state); + return $this->configuration['generatorOptions'][$optionName] ?? null; + } + + public function getGeneratorOptions(): array + { + return is_array($this->configuration['generatorOptions']) ? $this->configuration['generatorOptions'] : []; } } diff --git a/typo3/sysext/core/Classes/Schema/Field/StaticSelectFieldType.php b/typo3/sysext/core/Classes/Schema/Field/StaticSelectFieldType.php index a12f0a06eaf5..65c1c829a04d 100644 --- a/typo3/sysext/core/Classes/Schema/Field/StaticSelectFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/StaticSelectFieldType.php @@ -17,20 +17,28 @@ declare(strict_types=1); namespace TYPO3\CMS\Core\Schema\Field; +use TYPO3\CMS\Core\Schema\Struct\SelectItem; + /** * This is a select type without any MM or foreign table logic. * * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class StaticSelectFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class StaticSelectFieldType extends AbstractFieldType { public function getType(): string { return 'select'; } - public static function __set_state(array $state): self + /** + * @return SelectItem[] + */ + public function getItems(): array { - return new self(...$state); + return is_array($this->configuration['items'] ?? false) ? array_map( + static fn($item): SelectItem => SelectItem::fromTcaItemArray($item), + $this->configuration['items'] + ) : []; } } diff --git a/typo3/sysext/core/Classes/Schema/Field/TextFieldType.php b/typo3/sysext/core/Classes/Schema/Field/TextFieldType.php index ca3a479961c4..ab2c684c02d5 100644 --- a/typo3/sysext/core/Classes/Schema/Field/TextFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/TextFieldType.php @@ -20,7 +20,7 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class TextFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class TextFieldType extends AbstractFieldType { public function getType(): string { @@ -31,9 +31,4 @@ final readonly class TextFieldType extends AbstractFieldType implements FieldTyp { return $this->configuration['enableRichtext'] ?? false; } - - public static function __set_state(array $state): self - { - return new self(...$state); - } } diff --git a/typo3/sysext/core/Classes/Schema/Field/UserFieldType.php b/typo3/sysext/core/Classes/Schema/Field/UserFieldType.php index 93ba6caa5006..bcb5aa70af5c 100644 --- a/typo3/sysext/core/Classes/Schema/Field/UserFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/UserFieldType.php @@ -20,15 +20,15 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class UserFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class UserFieldType extends AbstractFieldType { public function getType(): string { return 'user'; } - public static function __set_state(array $state): self + public function getRenderType(): string { - return new self(...$state); + return $this->configuration['renderType'] ?? ''; } } diff --git a/typo3/sysext/core/Classes/Schema/Field/UuidFieldType.php b/typo3/sysext/core/Classes/Schema/Field/UuidFieldType.php index f8ad82a24bc7..a567ee4c49c3 100644 --- a/typo3/sysext/core/Classes/Schema/Field/UuidFieldType.php +++ b/typo3/sysext/core/Classes/Schema/Field/UuidFieldType.php @@ -20,15 +20,15 @@ namespace TYPO3\CMS\Core\Schema\Field; /** * @internal This is an experimental implementation and might change until TYPO3 v13 LTS */ -final readonly class UuidFieldType extends AbstractFieldType implements FieldTypeInterface +final readonly class UuidFieldType extends AbstractFieldType { public function getType(): string { return 'uuid'; } - public static function __set_state(array $state): self + public function getVersion(): int { - return new self(...$state); + return in_array($this->configuration['version'] ?? 0, [4, 6, 7], true) ? $this->configuration['version'] : 4; } } diff --git a/typo3/sysext/core/Classes/Schema/FieldFormat.php b/typo3/sysext/core/Classes/Schema/FieldFormat.php new file mode 100644 index 000000000000..305d25dd6454 --- /dev/null +++ b/typo3/sysext/core/Classes/Schema/FieldFormat.php @@ -0,0 +1,112 @@ +<?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; + +/** + * @internal This is an experimental implementation and might change until TYPO3 v13 LTS + */ +enum FieldFormat: string +{ + case Date = 'date'; + + case Datetime = 'datetime'; + + case Time = 'time'; + + case Timesec = 'timesec'; + + case Year = 'year'; + + case Int = 'int'; + + case Float = 'float'; + + case Number = 'number'; + + case Md5 = 'md5'; + + case Filesize = 'filesize'; + + case User = 'user'; + + case Undefined = ''; + + private const FORMAT_CONFIGURATION = [ + self::Date->value => [ + 'strftime', + 'option', + 'appendAge', + ], + self::Int->value => [ + 'base', + ], + self::Float->value => [ + 'precision', + ], + self::Number->value => [ + 'option', + ], + self::Filesize->value => [ + 'appendByteSize', + ], + self::User->value => [ + 'userFunc', + ], + ]; + + public static function fromTcaConfiguration(array $configuration): self + { + if (isset($configuration['config'])) { + $configuration = $configuration['config']; + } + if (isset($configuration['format'])) { + return match ($configuration['format']) { + 'date' => self::Date, + 'datetime' => self::Datetime, + 'time' => self::Time, + 'timesec' => self::Timesec, + 'year' => self::Year, + 'int' => self::Int, + 'float' => self::Float, + 'number' => self::Number, + 'md5' => self::Md5, + 'filesize' => self::Filesize, + 'user' => self::User, + default => throw new \UnexpectedValueException('Invalid format: ' . $configuration['format'], 1724744407), + }; + } + + return self::Undefined; + } + + public function getFormatConfiguration(array $configuration): array + { + if (isset($configuration['config'])) { + $configuration = $configuration['config']; + } + + if (!isset(self::FORMAT_CONFIGURATION[$this->value]) + || !is_array($configuration['format.'] ?? false) + || $configuration['format.'] === [] + ) { + return []; + } + + return array_filter($configuration['format.'], fn(string $option): bool => in_array($option, self::FORMAT_CONFIGURATION[$this->value], true), ARRAY_FILTER_USE_KEY); + } +} diff --git a/typo3/sysext/core/Classes/Schema/TcaSchema.php b/typo3/sysext/core/Classes/Schema/TcaSchema.php index 739c7d15ca95..e30ae41f93da 100644 --- a/typo3/sysext/core/Classes/Schema/TcaSchema.php +++ b/typo3/sysext/core/Classes/Schema/TcaSchema.php @@ -48,9 +48,15 @@ readonly class TcaSchema implements SchemaInterface return $this->name; } - public function getFields(): FieldCollection + public function getFields(...$fieldNames): FieldCollection { - return $this->fields; + if ($fieldNames === []) { + return $this->fields; + } + + return new FieldCollection( + array_filter(iterator_to_array($this->fields), static fn(FieldTypeInterface $field): bool => in_array($field->getName(), $fieldNames, true)) + ); } public function hasField(string $fieldName): bool diff --git a/typo3/sysext/styleguide/Configuration/TCA/tx_styleguide_elements_basic.php b/typo3/sysext/styleguide/Configuration/TCA/tx_styleguide_elements_basic.php index 2d9d0404c212..30c145cb28a0 100644 --- a/typo3/sysext/styleguide/Configuration/TCA/tx_styleguide_elements_basic.php +++ b/typo3/sysext/styleguide/Configuration/TCA/tx_styleguide_elements_basic.php @@ -1550,6 +1550,18 @@ backend_layout { 'format' => 'datetime', ], ], + 'none_4' => [ + 'label' => 'none_4', + 'description' => 'format=date with format configuration', + 'config' => [ + 'type' => 'none', + 'format' => 'date', + 'format.' => [ + 'option' => '%d-%m', + 'strftime' => true, + ], + ], + ], 'passthrough_1' => [ 'label' => 'passthrough_1', @@ -1914,7 +1926,7 @@ backend_layout { --div--;language, language_1, --div--;none, - none_1, none_2, none_3, + none_1, none_2, none_3, none_4, --div--;passthrough, passthrough_1, passthrough_2, --div--;user, diff --git a/typo3/sysext/styleguide/ext_tables.sql b/typo3/sysext/styleguide/ext_tables.sql index f30916b63a49..6da4ac743fb9 100644 --- a/typo3/sysext/styleguide/ext_tables.sql +++ b/typo3/sysext/styleguide/ext_tables.sql @@ -33,6 +33,7 @@ CREATE TABLE tx_styleguide_elements_basic ( none_1 text, none_2 text, none_3 text, + none_4 text, # type=passthrough needs manual configuration passthrough_1 text, -- GitLab