Important: #85044 - Filter disallowed properties in form editor

See Issue #85044

Description

The form editor save and preview actions now check the submitted form definition against configured possibilities within the form editor setup.

If a form element property is defined in the form editor setup then it means that the form element property can be written by the form editor. A form element property can be written if the property path is defined within the following form editor properties:

  • formElementsDefinition.<formElementType>.formEditor.editors.<index>.propertyPath
  • formElementsDefinition.<formElementType>.formEditor.editors.<index>.*.propertyPath
  • formElementsDefinition.<formElementType>.formEditor.editors.<index>.additionalElementPropertyPaths
  • formElementsDefinition.<formElementType>.formEditor.propertyCollections.<finishers|validators>.<index>.editors.<index>.additionalElementPropertyPaths

If a form editor property templateName is “Inspector-PropertyGridEditor” or “Inspector-MultiSelectEditor” or “Inspector-ValidationErrorMessageEditor” it means that the form editor property propertyPath is interpreted as a so called “multiValueProperty”. A “multiValueProperty” can contain any subproperties relative to the value from propertyPath which are valid. If formElementsDefinition.<formElementType>.formEditor.editors.<index>.templateName = “Inspector-PropertyGridEditor” and formElementsDefinition.<formElementType>.formEditor.editors.<index>.propertyPath = “options.xxx” then (for example) “options.xxx.yyy” is a valid property path to write.

If a form elements finisher|validator property is defined in the form editor setup then it means that the form elements finisher|validator property can be written by the form editor. A form elements finisher|validator property can be written if the property path is defined within the following form editor properties:

  • formElementsDefinition.<formElementType>.formEditor.propertyCollections.<finishers|validators>.<index>.editors.<index>.propertyPath
  • formElementsDefinition.<formElementType>.formEditor.propertyCollections.<finishers|validators>.<index>.editors.<index>.*.propertyPath

If a form elements finisher|validator property templateName is “Inspector-PropertyGridEditor” or “Inspector-MultiSelectEditor” or “Inspector-ValidationErrorMessageEditor” it means that the form editor property propertyPath is interpreted as a so called “multiValueProperty”. A “multiValueProperty” can contain any subproperties relative to the value from propertyPath which are valid. If formElementsDefinition.<formElementType>.formEditor.propertyCollections.<finishers|validators>.<index>.editors.<index>.templateName = “Inspector-PropertyGridEditor” and formElementsDefinition.<formElementType>.formEditor.propertyCollections.<finishers|validators>.<index>.editors.<index>.propertyPath = “options.xxx” that (for example) “options.xxx.yyy” is a valid property path to write.

If you use a custom form editor JavaScript “inspector editor” implementation (see https://docs.typo3.org/typo3cms/extensions/form/Concepts/FormEditor/Index.html#inspector) which does not define the writable property paths by one of the above described inspector editor properties (e.g propertyPath) within the form setup, you must provide the writable property paths with a hook. Otherwise the editor will fail when saving.

Connect to the hook:

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['buildFormDefinitionValidationConfiguration'][] = \Vendor\YourNamespace\YourClass::class;

Use the hook:

The hook must return an array with a set of ValidationDto objects.

/**
 * @param \TYPO3\CMS\Form\Domain\Configuration\FormDefinition\Validators\ValidationDto $validationDto
 * @return array
 */
public function addAdditionalPropertyPaths(\TYPO3\CMS\Form\Domain\Configuration\FormDefinition\Validators\ValidationDto $validationDto): array
{
    // Create a ValidationDto object for the form element type "Form" (:yaml:`formElementsDefinition.<formElementType>`).
    $formValidationDto = $validationDto->withFormElementType('Form');
    // Create a ValidationDto object for the finishers for the form element type "Form".
    $formFinishersValidationDto = $formValidationDto->withPropertyCollectionName('finishers');

    // Create a ValidationDto object for the form element type "Text" (:yaml:`formElementsDefinition.<formElementType>`).
    $textValidationDto = $validationDto->withFormElementType('Text');
    // Create a ValidationDto object for the validators for the form element type "Text".
    $textValidatorsValidationDto = $textValidationDto->withPropertyCollectionName('validators');

    // Create a ValidationDto object for the form element type "Date" (:yaml:`formElementsDefinition.<formElementType>`).
    $dateValidationDto = $validationDto->withFormElementType('Date');

    $propertyPaths = [
        // Register the property :yaml:`renderingOptions.my.custom.property` for the form element type "Form".
        // This property can now be written by the form editor.
        $formValidationDto->withPropertyPath('renderingOptions.my.custom.property'),

        // Register the property :yaml:`options.custom.property` for the finisher "MyCustomFinisher" for the form element type "Form".
        // "MyCustomFinisher" must be equal to the identifier property from
        // your custom inspector editor (:yaml:`formElementsDefinition.Form.formEditor.propertyCollections.finishers.<index>.editors.<index>.identifier`)
        // This property can now be written by the form editor.
        $formFinishersValidationDto->withPropertyCollectionElementIdentifier('MyCustomFinisher')->withPropertyPath('options.custom.property'),

        // Register the properties :yaml:`properties.my.custom.property` and :yaml:`properties.my.other.custom.property` for the form element type "Text".
        // This property can now be written by the form editor.
        $textValidationDto->withPropertyPath('properties.my.custom.property'),
        $textValidationDto->withPropertyPath('properties.my.other.custom.property'),

        // Register the property :yaml:`options.custom.property` for the validator "CustomValidator" for the form element type "Text".
        // "CustomValidator" must be equal to the identifier property from
        // your custom inspector editor (:yaml:`formElementsDefinition.Text.formEditor.propertyCollections.validators.<index>.editors.<index>.identifier`)
        // This property can now be written by the form editor.
        $textValidatorsValidationDto->withPropertyCollectionElementIdentifier('CustomValidator')->withPropertyPath('options.custom.property'),

        $textValidatorsValidationDto->withPropertyCollectionElementIdentifier('AnotherCustomValidator')->withPropertyPath('options.other.custom.property'),

        $dateValidationDto->withPropertyPath('properties.custom.property'),
        // ..
    ];

    return $propertyPaths;
}