---
title: "Validation settings"
manual: "Academic Profiles"
version: "2.4"
permalink: "https://docs.typo3.org/permalink/fgtclb/academic-persons:configuration-validations@2.4"
source: "Configuration/Validations/Index.rst"
rendered: "2026-10-26T16:44:14+00:00"
---

# Validation settings {#configuration-validations}

`Configuration/AcademicPersons/Settings.yaml` describes, per record type
and per field, whether a field is **required**, **read only** or **disabled**.

One file drives **both editing contexts**:

-   the TYPO3 backend record editor (FormEngine), through generated TCA, and
-   the frontend editing forms of [EXT:academic_persons_edit](https://extensions.typo3.org/extension/academic_persons_edit).

This is why the file ships with **academic_persons**, which owns the
records and their TCA, and not with the editing extension. The backend half
applies even when the editing extension is not installed.

> [!WARNING]
> **Attention**
>
> The syntax of this file is still considered experimental and may change in
> a future release.

## Where the sets live {#where-the-sets-live}

Six sets exist, one per editable record type. The set name selects the record
type, the keys below it are **property names** in camel case, and each property
carries a list of flags:

```yaml
validations:
  profile:
    firstName:
      - disabled
    website:
      - required
```

The six set names, and the records they configure:

| Set | Record |
| --- | --- |
| `profile` | Profile |
| `contract` | Contract |
| `emailAddress` | Email address |
| `phoneNumber` | Phone number |
| `physicalAddress` | Physical address |
| `profileInformation` | Profile information |

A property that is not listed is unconfigured: it is editable, not required, and
no validator runs for it.

## Available flags {#available-flags}

Flag names are matched case insensitively. Anything not listed here is ignored.

| Flag | Effect |
| --- | --- |
| `required` | The field must not be empty. Adds a *not empty* validation in the frontend and marks the field required in the backend. |
| `disabled` | The field must not be edited at all. See the note below. |
| `readonly` | The field is shown but cannot be written. |
| `frontendreadonly` | The field is shown but cannot be written in the frontend editing form. The backend record editor keeps it editable. See the note below. |
| `email` | The value must be a valid email address, and the field is rendered as an email input. |
| `number` | The field is rendered as a number input, and the backend record editor turns it into a TCA `number` field, which stores an integer. Use it for integer columns only, such as the `year` of a profile information. A postcode or a street number is not one: `01067` would be saved as `1067` and `12a` as `12`. No additional server side validation is performed. |

> [!NOTE]
> `disabled` and `readonly` both **cancel** `required`. A
> field that cannot be edited cannot be demanded from the editor, so combining
> them has no effect — the field is simply locked.
>
> `disabled` additionally implies `readonly`. FormEngine has no
> equivalent of the HTML `disabled` attribute, so a disabled field is
> presented as read only in the backend.
>
> `frontendreadonly` locks the field for profile owners only. It
> cancels `required` in the frontend editing form, because an owner
> cannot correct a value they cannot edit, while the backend record editor
> still requires the field. Listed together with `readonly` or
> `disabled`, the field is locked in the backend as well.

## Fields that are locked by default {#configuration-validations-defaults}

Three profile fields ship as `disabled`:

```yaml
validations:
  profile:
    firstName:
      - disabled
      - required
    middleName:
      - disabled
    lastName:
      - disabled
```

This is intentional. Profile names are usually owned by the connected frontend
user record — commonly fed from a directory service such as LDAP or Active
Directory, and synchronised into the profile — so they must not be overwritten
from an editing form.

The consequences, which surprise people who did not expect them:

-   **First name**, **Middle name** and **Last name**
    are **read only in the backend** record editor, for every backend user.
-   The same three fields are rendered disabled in the frontend editing form,
    and a value submitted for them is discarded on the server.

The `required` entry on `firstName` has no effect, because
`disabled` cancels it.

If the profile names are maintained in TYPO3 rather than synchronised from
elsewhere, remove those entries as described below.

## Effects in the TYPO3 backend {#effects-in-the-typo3-backend}

The settings are merged into the TCA of the matching table, so a field locked
with `readonly` or `disabled` is read only in the record editor and
a required field is marked as such. `frontendreadonly` is the one lock
that does not reach the TCA. The sets map to these tables:

| Set | Table |
| --- | --- |
| `profile` | `tx_academicpersons_domain_model_profile` |
| `contract` | `tx_academicpersons_domain_model_contract` |
| `emailAddress` | `tx_academicpersons_domain_model_email` |
| `phoneNumber` | `tx_academicpersons_domain_model_phone_number` |
| `physicalAddress` | `tx_academicpersons_domain_model_address` |
| `profileInformation` | `tx_academicpersons_domain_model_profile_information` |

The property name is translated to the database column automatically:
`firstName` addresses `first_name`. Two spellings of one property in
one set, `firstName` and `first_name`, therefore address the same
column, and the record editor takes the configuration of the one listed later.

## Effects in the frontend editing plugin {#effects-in-the-frontend-editing-plugin}

When [EXT:academic_persons_edit](https://extensions.typo3.org/extension/academic_persons_edit) is installed,
the same configuration is used three times:

1.  The form field is rendered with the matching `disabled`,
    `readonly` and `required` attributes.
1.  `required` and `email` add server side validation of the
    submitted form.
1.  A `disabled`, `readonly` or `frontendreadonly` property
    is **never written** to the record, whatever the request contains. This is
    deliberate: it protects already stored data, and it is what prevents a
    locked field from being emptied when a form is submitted.

> [!NOTE]
> Browsers ignore the `readonly` attribute on a select and on a
> checkbox. A select or checkbox configured `readonly` or
> `frontendreadonly` therefore stays operable in the form, and a value
> the owner changes there is discarded when the form is saved. Text fields
> and text areas are locked in the browser as well.
>
> A record an owner creates in the frontend, such as a new contract, is
> stored without a value for a field locked with `frontendreadonly`,
> even when the backend requires it. The backend record editor asks for it
> the next time the record is saved there.

## Overriding the settings {#configuration-validations-override}

Settings are collected from **all installed extensions**. Every package that
contains `Configuration/AcademicPersons/Settings.yaml` contributes, and
the package loaded last wins.

To change them for an installation:

1.  Add `Configuration/AcademicPersons/Settings.yaml` to your site
    package.
1.  Make the site package **depend on** **academic_persons** in its
    `composer.json` or `ext_emconf.php`, so that it is loaded after
    it.
1.  Repeat the **complete** `validations` block, see the warning below.
1.  Flush the TYPO3 caches.

> [!WARNING]
> The files are merged on the top level only. `validations` is a
> top-level key, so a site package that defines it replaces **all six sets**
> at once — the sets it does not repeat are lost, not inherited.
>
> Copy the whole `validations` block from
> `EXT:academic_persons/Configuration/AcademicPersons/Settings.yaml`
> and edit the copy. There is no syntax for removing a single flag from a
> single field.

Example — making the profile names editable again, in the backend and in the
frontend editing form. The other five sets are repeated unchanged and are
shortened here for readability:

```yaml
validations:
  profile:
    # The three name fields are no longer listed and are therefore editable.
    website:
      - required
  contract:
    position:
      - required
  emailAddress:
    email:
      - required
      - email
  phoneNumber:
    phoneNumber:
      - required
  physicalAddress:
    street:
      - required
  profileInformation:
    title:
      - required
```

Example - keeping the synchronised profile names away from their owners while
backend editors can still correct them. `frontendreadonly` replaces
`disabled`, `required` keeps the first and last name required in
the backend record editor, as the TCA of the profile table declares them, and
the other five sets are repeated unchanged as above:

```yaml
validations:
  profile:
    firstName:
      - required
      - frontendreadonly
    middleName:
      - frontendreadonly
    lastName:
      - required
      - frontendreadonly
```

> [!NOTE]
> Because both editing contexts read the same configuration, an override
> changes them together, with `frontendreadonly` as the one exception.
> Unlocking the profile names for the frontend editing form also makes those
> columns writable in the backend record editor.

There is no TypoScript and no site set equivalent for these settings.
