Attributes in Extbase
Deprecated since version 14.0
All Extbase attributes have been moved from the namespace
\TYPO3\ to the namespace \TYPO3\.
A class alias map is provided to allow further usage of the previous namespaces. Since the previous namespaces are considered deprecated, developers should migrate usages of the attribute classes once dropping TYPO3 13 support.
All available attributes for Extbase delivered by TYPO3 Core are placed within
the namespace
\TYPO3\ and can only be used with the
native PHP attribute syntax.
Changed in version 14.0
Using an attribute with the doctrine/annotations syntax is not supported anymore starting with TYPO3 14.0.
Example in EXT:blog_example
for the attribute
Lazy:
<?php
declare(strict_types=1);
namespace T3docs\BlogExample\Domain\Model;
use TYPO3\CMS\Extbase\Attribute\ORM\Lazy;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
class Post extends AbstractEntity
{
/**
* @var ObjectStorage<Post>
*/
#[Lazy()]
public ObjectStorage $relatedPosts;
}
Attributes provided by Extbase
The following attributes are provided by Extbase:
Validate
\TYPO3\:
Allows to configure validators for properties and method arguments.
See Using validation for Extbase models and controllers for details.
Can be used in the context of a model property.
Example:
<?php
declare(strict_types=1);
namespace T3docs\BlogExample\Domain\Model;
use TYPO3\CMS\Extbase\Attribute\Validate;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
class Blog extends AbstractEntity
{
#[Validate(
validator: 'StringLength',
options: ['maximum' => 150],
)]
public string $description = '';
}
Validate attributes for a controller action are executed additionally
to possible domain model validators.
IgnoreValidation
\TYPO3\:
Allows to ignore all Extbase default validations for a given argument
(for example a domain model object).
Used in context of a controller action argument.
Example:
<?php
declare(strict_types=1);
namespace T3docs\BlogExample\Controller;
use Psr\Http\Message\ResponseInterface;
use T3docs\BlogExample\Domain\Model\Blog;
use TYPO3\CMS\Extbase\Attribute\IgnoreValidation;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
final class BlogController extends ActionController
{
public function editAction(
#[IgnoreValidation]
Blog $blog,
): ResponseInterface {
// Do something
$this->view->assign('blog', $blog);
return $this->htmlResponse();
}
}
You can not exclude specific properties of a object specified in an argument.
If you need to exclude certain validators of a domain model, you could adapt the concept of a "Data Transfer Object" (DTO). You would create a distinct model variant of the main domain model, and exclude all the properties that you do not want validation for in your Extbase context, and transport the contents from and between your original domain model to this instance. Read more about this on https://usetypo3.com/dtos-in-extbase/ or see a CRUD example for this on https://github.com/garvinhicking/gh_validationdummy/
Warning
Ignore must not be used for domain models supporting
extbase file uploads, because this leads to a property mapping error.
ORM (object relational model) attributes
The following attributes can only be used on model properties:
Cascade
\TYPO3\:
Allows to remove child entities during deletion of aggregate root.
Extbase only supports the option "remove".
Example:
<?php
declare(strict_types=1);
namespace T3docs\BlogExample\Domain\Model;
use TYPO3\CMS\Extbase\Attribute\ORM\Cascade;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
final class Blog extends AbstractEntity
{
/**
* @var ObjectStorage<Post>
*/
#[Cascade(value: 'remove')]
public ObjectStorage $posts;
}
Transient
\TYPO3\:
Marks property as transient (not persisted).
Example:
Lazy
\TYPO3\:
Marks model property to be loaded lazily on first access.
Note
Lazy loading can greatly improve the performance of your actions.
Example:
<?php
declare(strict_types=1);
namespace T3docs\BlogExample\Domain\Model;
use TYPO3\CMS\Extbase\Attribute\ORM\Lazy;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
class Post extends AbstractEntity
{
/**
* @var ObjectStorage<Post>
*/
#[Lazy()]
public ObjectStorage $relatedPosts;
}
Combining attributes
Attributes can be combined. For example, "lazy loading" and "removal on cascade" are frequently combined:
<?php
declare(strict_types=1);
namespace T3docs\BlogExample\Domain\Model;
use TYPO3\CMS\Extbase\Attribute\ORM\Cascade;
use TYPO3\CMS\Extbase\Attribute\ORM\Lazy;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
class Post extends AbstractEntity
{
#[Lazy]
#[Cascade(value: 'remove')]
/**
* @var ObjectStorage<Comment>
*/
public ObjectStorage $comments;
}
Several validations can also be combined. See Using validation for Extbase models and controllers for details.
Migration and version compatibility (configuration arrays → attribute arguments)
With TYPO3 v14, passing a configuration array as the first argument to Extbase
attributes (for example
#,
#,
# or
#) has been deprecated
(Deprecation #97559).
TYPO3 v14 introduces a property-based configuration syntax using attribute
arguments.
The array-based syntax continues to work in TYPO3 v14 but will be removed with TYPO3 v15.
Important
There is no attribute configuration syntax that is compatible with both TYPO3 v13 and TYPO3 v14.
PHP attributes are parsed statically and cannot be conditionally defined based on the TYPO3 version. Extensions supporting TYPO3 v13 and v14 in the same release must therefore continue to use the array-based syntax and accept the deprecation warning in TYPO3 v14.
// TODO: Switch to named arguments when dropping TYPO3 v13 support (Deprecation #97559).
#[Cascade([
'value' => 'remove',
])]
#[Cascade(value: 'remove')]
TYPO3 Rector (
ssch/typo3-rector
) has rule
\Ssch\ to
automatically migrate from the annotation syntax to the attribute syntax.
Migrate from Extbase annotations to attributes
The native PHP attribute syntax has been introduced with PHP 8 and is fully supported by Extbase since TYPO3 12.
With TYPO3 14 the annotation syntax is not supported anymore and needs to be migrated to native PHP attributes:
-use TYPO3\CMS\Extbase\Annotation as Extbase;
+use TYPO3\CMS\Extbase\Attribute as Extbase;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
class MyModel extends AbstractEntity
{
- /**
- * @Extbase\Validate("NotEmpty")
- */
+ #[Extbase\Validate(validator: 'NotEmpty')]
protected string $foo = '';
}
TYPO3 Rector (
ssch/typo3-rector
) has rule
\Ssch\ to
automatically migrate from the annotation syntax to the attribute syntax.
See also