Field values

When a value is written, the DataHandler applies the TCA of the field: it trims, cuts to max, raises numbers to the lower range, keeps the stored value when a required value is empty, makes unique values unique and drops invalid email addresses. Each scenario below sends the same value once through the DataHandler, as the backend form sends it, and once through the setter of an Extbase model property, and compares the stored row.

Provenance

Tests ran on main (15.0-dev), which is assumed to behave as TYPO3 14.3.

Summary

9 scenarios, by Extbase status:

Comparison

ScenarioCoreExtbase
A value with surrounding spaces is trimmed The value " Title " (two spaces on either side) is sent for the input field trimmed, which has eval trim. DataHandler stores "Title". DeviatesExtbase stores " Title " with both spaces on either side, eval trim is not applied. The value comes from a string property.
A value longer than max is cut off A value of 20 characters ("01234567890123456789") is sent for the input field limited, which has max 10. DataHandler cuts the value to its first 10 characters and stores "0123456789". DeviatesExtbase stores all 20 characters, max of the field is not applied. The value comes from a string property.
A non numeric value in a number field is stored as zero The value "abc" is sent for the number field serial, which holds 5. DataHandler casts the value to an integer and stores 0. Same as coreExtbase also stores 0 in place of 5. An int property cannot hold "abc", so the model maps the number field to a string property: Extbase passes "abc" on unchanged and the database connection binds it as an integer for the column, which gives 0.
A number below the lower range is raised to it The value 0 is sent for the number field quantity, which has range lower 1. DataHandler raises the value to the lower bound and stores 1. DeviatesExtbase stores 0, the range of the field is not applied. The value comes from an int property.
An empty required value is not stored An empty string is sent for the required input field mandatory, which holds "Existing". DataHandler discards the value and leaves "Existing" in place. DeviatesExtbase stores the empty string and overwrites "Existing", required of the field is not checked. The value comes from a string property.
A duplicate unique value is made unique The value "taken", which entry 1 already holds, is sent for the input field code of entry 2, which has eval unique. DataHandler makes the value unique by appending a counter and stores "taken0". DeviatesExtbase stores "taken", so entries 1 and 2 hold the same code, eval unique is not applied. The value comes from a string property.
A duplicate value is made unique in the page The value "taken", which entry 1 on the same page already holds, is sent for the input field reference of entry 2, which has eval uniqueInPid. DataHandler makes the value unique within the page by appending a counter and stores "taken0". DeviatesExtbase stores "taken", so entries 1 and 2 on the same page hold the same reference, eval uniqueInPid is not applied. The value comes from a string property.
An invalid email address is dropped The value "not-an-email" is sent for the email field contact, which holds "old@example.com". DataHandler rejects the value as no valid email address, stores an empty string in its place and writes an error to errorLog. DeviatesExtbase stores "not-an-email" as it is, the email field is not validated. The value comes from a string property.
A date is stored as timestamp The ISO 8601 string "2023-11-14T12:00:00+00:00" is sent for the datetime field published, as the backend form sends it. DataHandler stores the Unix timestamp 1699963200. Same as coreExtbase also stores 1699963200. The value comes from a DateTimeImmutable property, which Extbase converts to a Unix timestamp for the datetime field.

Scenarios

A value with surrounding spaces is trimmed

Deviates

In 14.3

Core: The value " Title " (two spaces on either side) is sent for the input field trimmed, which has eval trim. DataHandler stores "Title".

Extbase: Extbase stores " Title " with both spaces on either side, eval trim is not applied. The value comes from a string property.

Target for 15.x

Extbase behaves as the core.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:91 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:112 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/Trimmed.csv (local)
SkipExtbase differs from core: it stores the value untrimmed, the eval trim of the field is not applied.
TestFieldValuesTest::aValueWithSurroundingSpacesIsTrimmedByExtbase (Failure without skip)
Assertion in data-set failed for "tx_extbasefacts_domain_model_entry:2":
Fields |Assertion|Record
trimmed|Title    |  Title

A value longer than max is cut off

Deviates

In 14.3

Core: A value of 20 characters ("01234567890123456789") is sent for the input field limited, which has max 10. DataHandler cuts the value to its first 10 characters and stores "0123456789".

Extbase: Extbase stores all 20 characters, max of the field is not applied. The value comes from a string property.

Target for 15.x

Extbase behaves as the core.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:136 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:157 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/CutOff.csv (local)
SkipExtbase differs from core: it stores all 20 characters, the max of the field is not applied.
TestFieldValuesTest::aValueLongerThanMaxIsCutOffByExtbase (Failure without skip)
Assertion in data-set failed for "tx_extbasefacts_domain_model_entry:2":
Fields |Assertion |Record
limited|0123456789|01234567890123456789

A non numeric value in a number field is stored as zero

Same as core

In 14.3

Core: The value "abc" is sent for the number field serial, which holds 5. DataHandler casts the value to an integer and stores 0.

Extbase: Extbase also stores 0 in place of 5. An int property cannot hold "abc", so the model maps the number field to a string property: Extbase passes "abc" on unchanged and the database connection binds it as an integer for the column, which gives 0.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:181 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:202 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/NonNumeric.csv (local)

A number below the lower range is raised to it

Deviates

In 14.3

Core: The value 0 is sent for the number field quantity, which has range lower 1. DataHandler raises the value to the lower bound and stores 1.

Extbase: Extbase stores 0, the range of the field is not applied. The value comes from an int property.

Target for 15.x

Extbase behaves as the core.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:223 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:244 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/BelowRange.csv (local)
SkipExtbase differs from core: it stores 0, the range lower of the field is not applied.
TestFieldValuesTest::aNumberBelowTheLowerRangeIsRaisedToItByExtbase (Failure without skip)
Assertion in data-set failed for "tx_extbasefacts_domain_model_entry:2":
Fields  |Assertion|Record
quantity|1        |0

An empty required value is not stored

Deviates

In 14.3

Core: An empty string is sent for the required input field mandatory, which holds "Existing". DataHandler discards the value and leaves "Existing" in place.

Extbase: Extbase stores the empty string and overwrites "Existing", required of the field is not checked. The value comes from a string property.

Target for 15.x

Extbase behaves as the core.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:268 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:288 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/EmptyRequired.csv (local)
SkipExtbase differs from core: it stores the empty string over the existing value, required of the field is not checked.
TestFieldValuesTest::anEmptyRequiredValueIsNotStoredByExtbase (Failure without skip)
Assertion in data-set failed for "tx_extbasefacts_domain_model_entry:2":
Fields   |Assertion|Record
mandatory|Existing |

A duplicate unique value is made unique

Deviates

In 14.3

Core: The value "taken", which entry 1 already holds, is sent for the input field code of entry 2, which has eval unique. DataHandler makes the value unique by appending a counter and stores "taken0".

Extbase: Extbase stores "taken", so entries 1 and 2 hold the same code, eval unique is not applied. The value comes from a string property.

Target for 15.x

Extbase behaves as the core.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:312 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:332 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/DuplicateUnique.csv (local)
SkipExtbase differs from core: it stores the duplicate value as it is, the eval unique of the field is not applied.
TestFieldValuesTest::aDuplicateUniqueValueIsMadeUniqueByExtbase (Failure without skip)
Assertion in data-set failed for "tx_extbasefacts_domain_model_entry:2":
Fields|Assertion|Record
code  |taken0   |taken

A duplicate value is made unique in the page

Deviates

In 14.3

Core: The value "taken", which entry 1 on the same page already holds, is sent for the input field reference of entry 2, which has eval uniqueInPid. DataHandler makes the value unique within the page by appending a counter and stores "taken0".

Extbase: Extbase stores "taken", so entries 1 and 2 on the same page hold the same reference, eval uniqueInPid is not applied. The value comes from a string property.

Target for 15.x

Extbase behaves as the core.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:356 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:376 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/DuplicateUniqueInPid.csv (local)
SkipExtbase differs from core: it stores the duplicate value as it is, the eval uniqueInPid of the field is not applied.
TestFieldValuesTest::aDuplicateValueIsMadeUniqueInThePageByExtbase (Failure without skip)
Assertion in data-set failed for "tx_extbasefacts_domain_model_entry:2":
Fields   |Assertion|Record
reference|taken0   |taken

An invalid email address is dropped

Deviates

In 14.3

Core: The value "not-an-email" is sent for the email field contact, which holds "old@example.com". DataHandler rejects the value as no valid email address, stores an empty string in its place and writes an error to errorLog.

Extbase: Extbase stores "not-an-email" as it is, the email field is not validated. The value comes from a string property.

Target for 15.x

Extbase behaves as the core.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:400 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:421 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/InvalidEmail.csv (local)
SkipExtbase differs from core: it stores the invalid address as it is, the email field is not validated.
TestFieldValuesTest::anInvalidEmailAddressIsDroppedByExtbase (Failure without skip)
Assertion in data-set failed for "tx_extbasefacts_domain_model_entry:2":
Fields |Assertion|Record
contact|         |not-an-email

A date is stored as timestamp

Same as core

In 14.3

Core: The ISO 8601 string "2023-11-14T12:00:00+00:00" is sent for the datetime field published, as the backend form sends it. DataHandler stores the Unix timestamp 1699963200.

Extbase: Extbase also stores 1699963200. The value comes from a DateTimeImmutable property, which Extbase converts to a Unix timestamp for the datetime field.

Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:445 (Core) (local)
Testtypo3/sysext/extbase/Tests/Functional/Persistence/Facts/FieldValuesTest.php:466 (Extbase) (local)
Filetypo3/sysext/extbase/Tests/Functional/Persistence/Facts/Fixtures/FieldValues/DateAsTimestamp.csv (local)