Extending an Extbase model

Once you have added an additional field to the TCA the new field will be displayed in the backend forms.

However, if the extension you are trying to extend is based on Extbase the new field is not available in the frontend out of the box. Further steps are needed to make the fields available. These steps will not work in all cases.

Quick overview

Follow these steps:

  1. Is your extension the only one trying to extend the original model within your installation?
  2. Find the original model. If this model has the modifier final refer to the extension's documentation on how to display additional fields.
  3. Find the original repository. Again, if the repository is final refer to the extension's documentation on how to display additional fields.
  4. Extend the original model in your custom extension or sitepackage.
  5. Register your extended model with the according database table in EXT:my_extension/Configuration/Extbase/Persistence/Classes.php.
  6. Extend the original repository in your custom extension or sitepackage.
  7. Register your extended repository to be used instead of the original one.

Step by step

Are you the only one trying to extend that model?

Within your installation you can search for other classes that are extending the original model or repository (see below).

If the model is already extended but you only need to create the fields for your current installation you can proceed by extending the extended model. In the following steps of this tutorial use the previously extended model as original model.

If the model has different Record types you can decide to introduce a new type and only extend that one type. This is, for example, commonly done when extending the model of EXT:news.

If you are planning to publish your extension that extends another extensions model, research on Packagist and the TER (TYPO3 extension repository) for extensions that are already extending the model. If necessary, put them in the conflict sections of you extensions composer.json and ext_emconf.php.

Find the original model

The model should be located in the original extension at path EXT:original_extension/Classes/Domain/Model/ or a subdirectory thereof. If the model is not found here it might

  • be situated in a different extension
  • not be an Extbase model (you cannot follow this tutorial then)

You can also try to debug the model in a Fluid template that outputs the model:

Some Fluid template that uses the model
<f:debug>{someModel}</f:debug>
Copied!

If you debugged the correct object the fully qualified PHP name of the model will appear in the debug output. This gives you further hints on where to find the associated class. You could, for example, do a full text search for the namespace of this class.

If the class of the model is final:

EXT:original_extension/Classes/Domain/Model/SomeModel.php
final class SomeModel {
    // ...
}
Copied!

It cannot be extended by means of this tutorial. Refer to the documentation of the original extension.

Find the original repository

In Extbase the repository of a model mostly has to have the same class name as the model, prefixed with "Repository". It has to be located in the same domain directory as the model, but in the subfolder Repository.

For example, if the model is found in Classes/Domain/Model/SomeModel.php the repository is located in Classes/Domain/Repository/SomeModelRepository.php.

  • If you do not find this repository but found the model the extension might not use an Extbase repository. This tutorial does not help you in this case as it can only be applied to Extbase repositories.
  • If you find a repository in this name scheme but it does not extend directly or indirectly the class TYPO3\CMS\Extbase\Persistence\Repository you are also not dealing with an Extbase repository.
  • If the repository is final it cannot be extended.

In all these cases refer to the extension's documentation on how to extend it.

Extend the original model

We assume you already extended the database table and TCA (table configuration array) as described in Extending TCA. Extend the original model by a custom class in your extension:

EXT:my_extension/Classes/Domain/Model/MyExtendedModel.php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Domain\Model;

use OriginalVendor\OriginalExtension\Domain\Model\SomeModel;

class MyExtendedModel extends SomeModel
{
    protected string $txMyExtensionAdditionalField;

    public function getTxMyExtensionAdditionalField(): string
    {
        return $this->txMyExtensionAdditionalField;
    }

    public function setTxMyExtensionAdditionalField(string $txMyExtensionAdditionalField): void
    {
        $this->txMyExtensionAdditionalField = $txMyExtensionAdditionalField;
    }
}
Copied!

Add all additional fields that you require. By convention the database fields are usually prefixed with your extension's name and so are the names in the model.

Register the extended model

The extended model needs to be registered for Extbase persistence in file Configuration/Extbase/Persistence/Classes.php and ext_localconf.php.

EXT:my_extension/Configuration/Extbase/Persistence/Classes.php
<?php

declare(strict_types=1);

use MyVendor\MyExtension\Domain\Model\MyExtendedModel;

return [
    MyExtendedModel::class => [
        'tableName' => 'tx_originalextension_somemodel',
    ],
];
Copied!
EXT:my_extension/ext_localconf.php
<?php

declare(strict_types=1);

use MyVendor\MyExtension\Domain\Model\MyExtendedModel;
use OriginalVendor\OriginalExtension\Domain\Model\SomeModel;

defined('TYPO3') or die('Access denied.');

$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][SomeModel::class] = [
    'className' => MyExtendedModel::class,
];
Copied!

Extend the original repository (optional)

Likewise extend the original repository:

EXT:my_extension/Classes/Domain/Repository/MyExtendedModelRepository.php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\Domain\Repository;

use OriginalVendor\OriginalExtension\Domain\Repository\SomeModelRepository;

class MyExtendedModelRepository extends SomeModelRepository
{
    /* Unless you need additional methods you can leave the class body empty */
}
Copied!

The rule that a repository must follow the name schema of the model also applies when extending model and repository. So the new repository's name must end on "Repository" and it must be in the directory Domain/Repository.

If you have no need for additional repository methods you can leave the body of this class empty. However, for Extbase internal reasons you have to create this repository even if you need no additional functionality.

Register the extended repository

The extended repository needs to be registered with Extbase in your extensions EXT:my_extension/ext_localconf.php. This step tells Extbase to use your repository instead of the original one whenever the original repository is requested via Dependency Injection in a controller or service.

EXT:my_extension/ext_localconf.php
<?php

declare(strict_types=1);

use MyVendor\MyExtension\Domain\Repository\MyExtendedRepository;
use OriginalVendor\OriginalExtension\Domain\Repository\SomeRepository;

defined('TYPO3') or die('Access denied.');

$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][SomeRepository::class] = [
    'className' => MyExtendedRepository::class,
];
Copied!

Alternative strategies to extend Extbase models

There is a dedicated TYPO3 extension to extend models and functions to classes by implementing the proxy pattern: Extbase Domain Model Extender (evoweb/extender).

This extension can - for example - be used to Extend models of tt_address.

The commonly used extension EXT:news (georgringer/news) supplies a special generator that can be used to add custom fields to news models.