.. include:: /Includes.rst.txt


.. _concepts-validators:

Validators
==========

The form framework ships a set of server-side validators (derived from Extbase
validators) which you can use in form elements. Some validators can only
be used for certain elements, e.g. the "Date range validator" can only be used for
"Date" elements. Some form elements
(like "Email") come with validators.

You can define your own validation error messages using the ``validationErrorMessages``
property. These error messages can also be set in the form editor.


.. _concepts-validators-client-side-validation:

Client-side validation
----------------------

In the form framework, HTML 5-based frontend validation can be added to form
elements, but JavaScript validation is not included. The TYPO3 core have no plans to
add this functionality at the current time. However, you can
add it yourself if required. Examples of reliable and well-maintained projects are
`Parsley <https://github.com/guillaumepotier/Parsley.js>`_
and `jQuery Validation <https://github.com/jquery-validation/jquery-validation>`__.


.. _concepts-validators-localization-client-side-validations:

Localization of client side validation
""""""""""""""""""""""""""""""""""""""

Display of validation messages is browser-specific and not generated by TYPO3 so
these messages cannot easily be changed. However, you can use JavaScript to change
validation messages. See `Stack Overflow <http://stackoverflow.com/questions/5272433/html5-form-required-attribute-set-custom-validation-message>`__
for more information.


.. _concepts-validators-server-side-validation:

Server-side validation
----------------------


.. _concepts-validators-alphanumeric:

Alphanumeric validator (:yaml:`Alphanumeric`)
"""""""""""""""""""""""""""""""""""""""""""""

The :ref:`"Alphanumeric validator"<prototypes.prototypeIdentifier.validatorsdefinition.alphanumeric>`
checks for alphanumeric strings. Alphanumeric is defined as a combination of
alphabetic and numeric characters `[A-Z + 0-9]`.


.. _concepts-validators-count:

Number of submitted values validator (:yaml:`Count`)
""""""""""""""""""""""""""""""""""""""""""""""""""""

The :ref:`"Number of submitted values validator"<prototypes.prototypeIdentifier.validatorsdefinition.count>`
checks if a value contains a specific number of elements. The
validator has two options:

- Minimum [:yaml:`options.minimum`]: The minimum count to accept.
- Maximum [:yaml:`options.maximum`]: The maximum count to accept.

..  versionadded:: 14.2
    :changelog: feature-105708-1739721600

Use the :yaml:`Count` validator with :yaml:`FileUpload` and
:yaml:`ImageUpload` elements to limit the number of uploaded files. The
element property :yaml:`multiple` must be enabled.


.. _concepts-validators-date_range:

Date range validator (:yaml:`DateRange`)
""""""""""""""""""""""""""""""""""""""""

The :ref:`"Date range validator"<prototypes.prototypeIdentifier.validatorsdefinition.daterange>`
checks if a value is a valid DateTime object and within a specified
date range. The range can be defined by providing a minimum and/or maximum date.
The validator has two options:

-   Format [:yaml:`options.format`]: The format of the absolute minimum and
    maximum dates. Default: [:yaml:`Y-m-d`].
-   Minimum date [:yaml:`options.minimum`]: The minimum date. Use an absolute
    date in the format `Y-m-d` or a relative date expression.
-   Maximum date [:yaml:`options.maximum`]: The maximum date. Use an absolute
    date in the format `Y-m-d` or a relative date expression.

Absolute dates use the format 'Y-m-d', which represents the
`RFC 3339 <https://www.w3.org/TR/2011/WD-html-markup-20110405/input.date.html>`__
'full-date' format.

..  versionadded:: 14.2
    :changelog: feature-106681-1740000000

    Before, the options :yaml:`minimum` and :yaml:`maximum` only accepted
    absolute dates.

Relative date expressions follow the syntax of the PHP function
`strtotime() <https://www.php.net/strtotime>`__, for example `today`,
`tomorrow`, `-18 years`, or `+1 month`. They are evaluated when the form is
validated. You can mix absolute and relative dates.

The following example accepts only dates of birth at least 18 years in the
past:

..  code-block:: yaml

    type: Date
    identifier: date-of-birth
    label: 'Date of birth'
    validators:
      -
        identifier: DateRange
        options:
          minimum: '1900-01-01'
          maximum: '-18 years'

The HTML attributes `min` and `max` of the rendered date input can also
contain relative date expressions. They are resolved to absolute `Y-m-d`
dates when the form is rendered.

The input must be a DateTime object. This input can be tested against a minimum
date and a maximum date. The minimum date and the maximum date are strings. The minimum
and maximum date can be configured through the validator options.


.. _concepts-validators-date_time:

Date/time validator (:yaml:`DateTime`)
"""""""""""""""""""""""""""""""""""""""

The :ref:`"Date/time validator"<prototypes.prototypeIdentifier.validatorsdefinition.datetime>`
checks if a value is a valid DateTime object. The date string is
expected to be formatted according to the `W3C standard <http://www.w3.org/TR/NOTE-datetime.html>`__
which is `YYYY-MM-DDT##:##:##+##:##`, for example `2005-08-15T15:52:01+00:00`.


.. _concepts-validators-email:

Email validator (:yaml:`EmailAddress`)
""""""""""""""""""""""""""""""""""""""

The :ref:`"Email validator"<prototypes.prototypeIdentifier.validatorsdefinition.emailaddress>`
checks if a value is a valid email address. The format of a valid email
address is defined in `RFC 3696 <https://tools.ietf.org/html/rfc3696>`__.
This standard allows international characters and multiple
`@` signs.


.. _concepts-validators-filesize:

File size validator (:yaml:`FileSize`)
""""""""""""""""""""""""""""""""""""""

The :ref:`"File size validator"<prototypes.prototypeIdentifier.validatorsdefinition.filesize>`
validates the size of a file resource. The validator has two options:

-   Minimum [:yaml:`options.minimum`]: The minimum file size. Use the
    format `<size>B|K|M|G`. For example: `10M` is 10 Megabytes.
-   Maximum [:yaml:`options.maximum`]: The maximum file size. Use the
    format `<size>B|K|M|G`. For example: `10M` is 10 Megabytes.

Use the format `<size>B|K|M|G` for file size, for example, `10M`
is 10 megabytes. Note: the maximum file size also depends on the :file:`php.ini`
settings of your environment.


.. _concepts-validators-floating_point:

Floating-point number validator (:yaml:`Float`)
"""""""""""""""""""""""""""""""""""""""""""""""

The :ref:`"Floating-point number validator"<prototypes.prototypeIdentifier.validatorsdefinition.float>`
checks if a value is of type float or a string matching the regular
expression `[0-9.e+-]`.


.. _concepts-validators-integer:

Integer number validator (:yaml:`Integer`)
""""""""""""""""""""""""""""""""""""""""""

The :ref:`"Integer number validator"<prototypes.prototypeIdentifier.validatorsdefinition.integer>`
checks if a value is a valid integer.


.. _concepts-validators-empty:

Empty validator (:yaml:`NotEmpty`)
""""""""""""""""""""""""""""""""""

The :ref:`"Empty validator"<prototypes.prototypeIdentifier.validatorsdefinition.notempty>`
checks if a value is not empty (i.e. equal to NULL, empty string, empty array or empty
object).


.. _concepts-validators-number:

Number validator (:yaml:`Number`)
"""""""""""""""""""""""""""""""""

The :ref:`"Number validator"<prototypes.prototypeIdentifier.validatorsdefinition.number>`
checks if a value is a number.


.. _concepts-validators-number_range:

Number range validator (:yaml:`NumberRange`)
""""""""""""""""""""""""""""""""""""""""""""

The :ref:`"Number range validator"<prototypes.prototypeIdentifier.validatorsdefinition.numberrange>`
checks if a value is a number in a specified range. The validator has
two options:

- Minimum [:yaml:`options.minimum`]: The minimum value.
- Maximum [:yaml:`options.maximum`]: The maximum value.


.. _concepts-validators-regular_expressions:

Regular expression validator (:yaml:`RegularExpression`)
""""""""""""""""""""""""""""""""""""""""""""""""""""""""

The :ref:`"Regular expression validator"<prototypes.prototypeIdentifier.validatorsdefinition.regularexpression>`
checks if a value matches a specified regular expression. Delimiters
or modifiers are not supported. The validator has one option:

- Regular expression [:yaml:`options.regularExpression`]: The regular expression
  to use for validation, used as given.

As an example, a user submits a domain name and the submitted value should only
contain the second and the top level domain, i.e. "typo3.org" instead of
"https://typo3.org". The regular expression for this would be :code:`/^[-a-z0-9]+\.[a-z]{2,6}$/`.

.. _concepts-validators-string_length:

String length validator (:yaml:`StringLength`)
""""""""""""""""""""""""""""""""""""""""""""""

The :ref:`"String length validator"<prototypes.prototypeIdentifier.validatorsdefinition.stringlength>`
checks if a value is a valid string and its length is within a specified
range. The validator has two options:

- Minimum [:yaml:`options.minimum`]: The minimum length of a valid string.
- Maximum [:yaml:`options.maximum`]: The maximum length of a valid string.


.. _concepts-validators-text:

Non-XML text validator (:yaml:`Text`)
"""""""""""""""""""""""""""""""""""""

The :ref:`"Non-XML text validator"<prototypes.prototypeIdentifier.validatorsdefinition.text>`
checks if a value is a valid piece of text (containing no XML tags). This basically
means that tags are stripped out. In this special case quotes are not encoded
(see `filter_var() <https://php.net/filter_var>`__ for more information.

Be aware that the value of this check entirely depends on the output
context. The validated text is not expected to be secure.
If you want to be sure of that, use a customized regular expression or filter on
output.


.. _concepts-validators-validation-message-translation:

Translation of validation messages
----------------------------------

To learn more about this topic, see :ref:`here<concepts-frontendrendering-translation-validationerrors>`.


.. _concepts-validators-customvalidatorimplementations:

Custom validator implementations
--------------------------------

Validators belong to configuration ``prototypes`` in a ``validatorsDefinition``.
Set the ``implementationClassName`` property of the ``prototype`` to your
own validator classes.

.. code-block:: yaml

   prototypes:
     standard:
       validatorsDefinition:
         Custom:
           implementationClassName: 'VENDOR\MySitePackage\Domain\Validation\CustomValidator'

Add ``options`` to your validator and provide a default value ``yourCustomOption``:

.. code-block:: yaml

   prototypes:
     standard:
       validatorsDefinition:
         Custom:
           implementationClassName: 'VENDOR\MySitePackage\Domain\Validation\CustomValidator'
           options:
             yourCustomOption: 'Jurian'

You can override the default value in your ``form definition``:

.. code-block:: yaml
   :emphasize-lines: 13

   identifier: sample-form
   label: 'Simple Contact Form'
   prototype: standard
   type: Form

   renderables:
     -
       identifier: subject
       label: 'Name'
       type: Text
       validators:
         -
           identifier: Custom
           options:
             yourCustomOption: 'Mathias'

As mentioned above, EXT:form uses Extbase validators. That said,
your own validators should extend :php:`\TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator`.
Read more in "TYPO3 Explained":
:ref:`t3coreapi:extbase_domain_validator`.


..  _concepts-validators-customvalidatorimplementations-objectstorage:

Validating multi-value fields
"""""""""""""""""""""""""""""

..  versionadded:: 14.2
    :changelog: feature-105708-1739721600

Some form elements submit several values as an
:php-short:`\TYPO3\CMS\Extbase\Persistence\ObjectStorage`, for example a
:yaml:`FileUpload` element with :yaml:`multiple` enabled. By default, a
validator receives the whole
:php-short:`\TYPO3\CMS\Extbase\Persistence\ObjectStorage`. Use this for
validators that check the collection as a whole, such as the :yaml:`Count`
validator.

If a validator checks single items, implement the marker interface
:php-short:`\TYPO3\CMS\Form\Mvc\Validation\ObjectStorageElementValidatorInterface`.
The validator is then called once for each item. The validators
:php-short:`\TYPO3\CMS\Form\Mvc\Validation\MimeTypeValidator` and
:php-short:`\TYPO3\CMS\Form\Mvc\Validation\FileSizeValidator` work this way.

..  code-block:: php
    :caption: EXT:my_site_package/Classes/Domain/Validation/CustomFileValidator.php

    use TYPO3\CMS\Extbase\Validation\Validator\AbstractValidator;
    use TYPO3\CMS\Form\Mvc\Validation\ObjectStorageElementValidatorInterface;

    final class CustomFileValidator extends AbstractValidator implements
      ObjectStorageElementValidatorInterface
    {
      public function isValid(mixed $value): void
      {
        // $value is a single item of the ObjectStorage,
        // for example a FileReference
      }
    }

For values that are not an
:php-short:`\TYPO3\CMS\Extbase\Persistence\ObjectStorage`, the interface
has no effect.
