Annotations

All available annotations for Extbase delivered by TYPO3 Core are placed within the namespace \TYPO3\CMS\Extbase\Annotation.

Changed in version 12.0: Starting with TYPO3 v12.0 Extbase annotations can be supplied as PHP 8 native attributes.

Attention

Even if you use PHP 8.0 with TYPO3 v11 LTS native attributes do not work below TYPO3 v12.0. To stay compatible with both TYPO3 v11 and v12, continue to use the Extbase annotations as doc-block comments.

Example in EXT:blog_example for the annotation Lazy:

EXT:blog_example/Classes/Domain/Model/Blog.php, modified
<?php

declare(strict_types=1);

namespace T3docs\BlogExample\Domain\Model;

use TYPO3\CMS\Extbase\Annotation\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;

    /**
     * Use annotations instead for compatibility with TYPO3 v11:
     * @var ObjectStorage<Post>
     * @Lazy
     */
    public ObjectStorage $relatedPosts2;
}

Annotations provided by Extbase

The following annotations are provided Extbase:

Validate

\TYPO3\CMS\Extbase\Annotation\Validate: Allows to configure validators for properties and method arguments. See Validation for details.

Can be used in the context of a model property.

Example:

EXT:blog_example/Classes/Domain/Model/Blog.php, modified
<?php

declare(strict_types=1);

namespace T3docs\BlogExample\Domain\Model;

use TYPO3\CMS\Extbase\Annotation\Validate;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

class Blog extends AbstractEntity
{
    #[Validate([
        'validator' => 'StringLength',
        'options' => ['maximum' => 150],
    ])]
    public string $description = '';

    /**
     * Use annotations instead for compatibility with TYPO3 v11:
     *
     * @Validate("StringLength", options={"maximum": 150})
     */
    public string $description2 = '';
}

IgnoreValidation

\TYPO3\CMS\Extbase\Annotation\IgnoreValidation(): Allows to ignore Extbase default validation for a given argument.

Used in context of a controller action.

Example:

EXT:blog_example/Classes/Controller/BlogController.php, modified
<?php

declare(strict_types=1);

namespace T3docs\BlogExample\Controller;

use Psr\Http\Message\ResponseInterface;
use T3docs\BlogExample\Domain\Model\Blog;
use TYPO3\CMS\Extbase\Annotation\IgnoreValidation;
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;

final class BlogController extends ActionController
{
    #[IgnoreValidation(['argumentName' => 'newBlog'])]
    public function newAction(?Blog $newBlog = null): ResponseInterface
    {
        // Do something
        return $this->htmlResponse();
    }

    /**
     * Use annotations instead for compatibility with TYPO3 v11:
     * @IgnoreValidation("newBlog")
     */
    public function newAction2(?Blog $newBlog = null): ResponseInterface
    {
        // Do something
        return $this->htmlResponse();
    }
}

ORM (object relational model) annotations

The following annotations can only be used on model properties:

Cascade

\TYPO3\CMS\Extbase\Annotation\ORM\Cascade("remove"): Allows to remove child entities during deletion of aggregate root.

Extbase only supports the option "remove".

Example:

EXT:blog_example/Classes/Domain/Model/Blog.php, modified
<?php

declare(strict_types=1);

namespace T3docs\BlogExample\Domain\Model;

use TYPO3\CMS\Extbase\Annotation\ORM\Cascade;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;

final class Blog extends AbstractEntity
{
    /**
     * @var ObjectStorage<Post>
     */
    #[Cascade('remove')]
    public $posts;

    /**
     * Use annotations instead for compatibility with TYPO3 v11:
     *
     * @var ObjectStorage<Post>
     * @Cascade("remove")
     */
    public $posts2;
}

Transient

\TYPO3\CMS\Extbase\Annotation\ORM\Transient: Marks property as transient (not persisted).

Example:

EXT:blog_example/Classes/Domain/Model/Post.php, modified
<?php

declare(strict_types=1);

namespace T3docs\BlogExample\Domain\Model;

use TYPO3\CMS\Extbase\Annotation\ORM\Transient;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;

final class Person extends AbstractEntity
{
    #[Transient()]
    protected string $fullname = '';

    /**
     * Use annotations instead for compatibility with TYPO3 v11:
     * @Transient
     */
    protected string $fullname2 = '';
}

Lazy

\TYPO3\CMS\Extbase\Annotation\ORM\Lazy: Marks model property to be loaded lazily on first access.

Note

Lazy loading can greatly improve the performance of your actions.

Example:

EXT:blog_example/Classes/Domain/Model/Post.php, modified
<?php

declare(strict_types=1);

namespace T3docs\BlogExample\Domain\Model;

use TYPO3\CMS\Extbase\Annotation\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;

    /**
     * Use annotations instead for compatibility with TYPO3 v11:
     * @var ObjectStorage<Post>
     * @Lazy
     */
    public ObjectStorage $relatedPosts2;
}

Combining annotations

Annotations can be combined. For example, "lazy loading" and "removal on cascade" are frequently combined:

EXT:blog_example/Classes/Domain/Model/Post.php, modified
<?php

declare(strict_types=1);

namespace T3docs\BlogExample\Domain\Model;

use TYPO3\CMS\Extbase\Annotation\ORM\Cascade;
use TYPO3\CMS\Extbase\Annotation\ORM\Lazy;
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;

class Post extends AbstractEntity
{
    #[Lazy()]
    #[Cascade('remove')]
    /**
     * @var ObjectStorage<Comment>
     */
    public ObjectStorage $comments;

    /**
     * @var ObjectStorage<Comment>
     * @Lazy
     * @Cascade("remove")
     */
    public ObjectStorage $comments2;
}

Several validations can also be combined. See Validation for details.