Attention
TYPO3 v11 has reached end-of-life as of October 31th 2024 and is no longer being maintained. Use the version switcher on the top left of this page to select documentation for a supported version of TYPO3.
Need more time before upgrading? You can purchase Extended Long Term Support (ELTS) for TYPO3 v11 here: TYPO3 ELTS.
Validator
See also
- Validation for general validation in Extbase.
Custom validators are located in the directory Classes/
and therefore in the namespace \Vendor\
.
All validators extend the Abstract
(\TYPO3\
).
Note
In the package \TYPO3\
Extbase
offers many validators for default requirements like the validation of
emails, numbers and strings. You do not need to implement such basic
checks yourself.
Custom validator for a property of the domain model
When the standard validators provided by Extbase are not sufficient you can write a custom validators to use on the property of a domain model:
final class TitleValidator extends AbstractValidator
{
protected function isValid(mixed $value): void
{
// $value is the title string
if (str_starts_with('_', $value)) {
$errorString = 'The title may not start with an underscore. ';
$this->addError($errorString, 1297418976);
}
}
}
The method is
does not return a value. In case of an error it
adds an error to the validation result by calling method add
.
The long number added as second parameter of this function is the current UNIX
time in the moment the error message was first introduced. This way all errors
can be uniquely identified.
This validator can be used for any string property of model now by including it in the annotation of that parameter:
use TYPO3\CMS\Extbase\Annotation\Validate;
class Blog extends AbstractEntity
{
/**
* @Validate("FriendsOfTYPO3\BlogExample\Domain\Validator\TitleValidator")
*/
public string $title = '';
}
Note
Validators added to a property of a model are executed whenever an object of that model is passed to a controller action as a parameter.
The validation of the parameter can be disabled by the annotation IgnoreValidation.
Complete domain model validation
At certain times in the life cycle of a model it can be necessary to validate the complete domain model. This is usually done before calling a certain action that will persist the object.
use FriendsOfTYPO3\BlogExample\Domain\Model\Blog;
use TYPO3\CMS\Extbase\Utility\LocalizationUtility;
final class BlogValidator extends AbstractValidator
{
protected function isValid(mixed $value): void
{
if (!$value instanceof Blog) {
$errorString = 'The blog validator can only handle classes '
. 'of type FriendsOfTYPO3\BlogExample\Domain\Validator\Blog. '
. $value::class . ' given instead.';
$this->addError($errorString, 1297418975);
}
if ($value->getCategories()->count() > 3) {
$errorString = LocalizationUtility::translate(
'error.Blog.tooManyCategories',
'BlogExample'
);
// Add the error to the property if it is specific to one property
$this->addErrorForProperty('categories', $errorString, 1297418976);
}
if (strtolower($value->getTitle()) === strtolower($value->getSubtitle())) {
$errorString = LocalizationUtility::translate(
'error.Blog.invalidSubTitle',
'BlogExample'
);
// Add the error directly if it takes several properties into account
$this->addError($errorString, 1297418974);
}
}
}
If the error is related to a specific property of the domain object, the
function add
should be used instead of add
.
The validator is used as annotation in the action methods of the controller:
use FriendsOfTYPO3\BlogExample\Domain\Model\Blog;
use FriendsOfTYPO3\BlogExample\Exception\NoBlogAdminAccessException;
use Psr\Http\Message\ResponseInterface;
use TYPO3\CMS\Extbase\Annotation\Validate;
class BlogController extends AbstractController
{
/**
* Updates an existing blog
*
* $blog is a not yet persisted clone of the original blog containing
* the modifications
*
* @Validate(param="blog", validator="FriendsOfTYPO3\BlogExample\Domain\Validator\BlogValidator")
* @throws NoBlogAdminAccessException
*/
public function updateAction(Blog $blog): ResponseInterface
{
$this->checkBlogAdminAccess();
$this->blogRepository->update($blog);
$this->addFlashMessage('updated');
return $this->redirect('index');
}
}