Extending an Extbase model
Once you have added a new field to the TCA it 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:
- Is your extension the only extension trying to extend the original model in your installation?
- Find the original model.
If the model has the
finalmodifier, refer to the extension documentation on how to display additional fields. - Find the original repository.
If the repository is
final, refer to the extension documentation on how to display additional fields. - Extend the original model in your extension or sitepackage.
- Register your extended model
with the corresponding database table in
EXT:my_extension/Configuration/Extbase/Persistence/Classes.php. - Extend the original repository in your extension or sitepackage.
- Register your extended repository so that it is used instead of the original one.
Step by step
Are you the only one trying to extend that model?
Search for other classes in your installation that extend 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 rest of this tutorial use the extended model as the original model.
If the model has different record types you can add a new type and only extend that one type. This is commonly done when extending the georgringer/news model.
If you are planning to publish this extension, search
Packagist and the
TER (TYPO3 extension repository) for
extensions that also extend the original model. If necessary, put them in
the conflict sections of your extension's composer.json and
ext_emconf.php.
Finding the original model
The model should be located in the original extension in
EXT: or a subdirectory. If the
model is not there it might:
- be located in a different extension
- not be an Extbase model (then you cannot follow this tutorial)
You can also try debugging the model with a Fluid template that outputs the model:
<f:debug>{someModel}</f:debug>
If you debugged the correct object, the fully qualified PHP name of the model will appear in the debug output. This will give you further hints on where to find the associated class. You could, for example, do a full text search for the namespace of the class.
If the class of the model is final:
final class SomeModel {
// ...
}
it cannot be extended using the instructions in this tutorial. Refer to the documentation of the original extension.
Finding the original repository
In Extbase the repository of a model usually has the same class name as
the model, prefixed with "Repository". It is located in the same domain
directory as the model, but in the Repository subfolder.
For example, if the model is Classes/Domain/Model/SomeModel.php
the repository is located in
Classes/Domain/Repository/SomeModelRepository.php.
- If you can't find the repository but have found the model, the extension might not be using an Extbase repository. This tutorial will not help you in this case as it is only relevant for Extbase repositories.
- If you find a repository according to this naming scheme but it does not extend
- the class
\TYPO3\directly or indirectly, it is also not an Extbase repository.CMS\ Extbase\ Persistence\ Repository - If the repository is final it cannot be extended.
In all these cases refer to the extension documentation on how to extend it.
Extend the original model
We assume that you have already extended the database table and TCA (table configuration array) as described in Extending TCA. Extend the original model in your extension using a class:
<?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;
}
}
Add all the additional fields that you require. By convention the database fields and the model names are prefixed with the name of your extension.
Register the extended model
The extended model needs to be registered for Extbase persistence in files
Configuration/Extbase/Persistence/Classes.php and ext_localconf.php.
<?php
declare(strict_types=1);
use MyVendor\MyExtension\Domain\Model\MyExtendedModel;
return [
MyExtendedModel::class => [
'tableName' => 'tx_originalextension_somemodel',
],
];
<?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,
];
Extend the original repository (optional)
Similarly, extend the original repository:
<?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 */
}
The rule that a repository must follow the naming schema of the model also
applies when extending model and repository. So the new repository's name must
end with "Repository" and it must be in the Domain/ directory.
If you don't need additional repository methods you can leave the body of this class empty. However, for internal Extbase reasons you have to create the repository even if you don't add additional functionality.
Register the extended repository
The extended repository needs to be registered with Extbase in your extension file
EXT:my_extension/ext_localconf.php. This 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.
<?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,
];
Alternative strategies to extend Extbase models
There is a TYPO3 extension that extends models and functions to classes by implementing the proxy pattern: Extbase Domain Model Extender (evoweb/extender).
This extension can be used to extend models of tt_address, for example.
The popular extension EXT: has a special
generator that can be used to add new fields to news models.