Persistence
It is possible to define models that are not persisted to the database. However, in the most common use cases you will want to save your model to the database and load it from there. If you want to extend an existing model you can also follow the steps on this page. See also Tutorial: Extending an Extbase model.
Connecting the model to the database
The SQL structure for the database needs to be defined in the file
EXT:{ext_key}/ext_tables.sql. An Extbase model requires
a valid TCA for the table that should be used as a base for the model.
Therefore you have to create a TCA definition in file
EXT:
.
It is recommended to stick to the following naming scheme for the table:
tx_{extkey}_domain_model_{mymodel}
tx_blogexample_domain_model_info
The SQL table for the model can be defined like this:
CREATE TABLE tx_blogexample_domain_model_info (
name varchar(255) DEFAULT '' NOT NULL,
post int(11) DEFAULT '0' NOT NULL
);
The according TCA definition could look like that:
<?php
return [
'ctrl' => [
'title' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xlf:tx_blogexample_domain_model_info',
'label' => 'name',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'versioningWS' => true,
'transOrigPointerField' => 'l10n_parent',
'transOrigDiffSourceField' => 'l10n_diffsource',
'languageField' => 'sys_language_uid',
'translationSource' => 'l10n_source',
'origUid' => 't3_origuid',
'delete' => 'deleted',
'sortby' => 'sorting',
'enablecolumns' => [
'disabled' => 'hidden',
],
'iconfile' => 'EXT:blog_example/Resources/Public/Icons/icon_tx_blogexample_domain_model_tag.gif',
],
'columns' => [
'name' => [
'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xlf:tx_blogexample_domain_model_info.name',
'config' => [
'type' => 'input',
'size' => 20,
'eval' => 'trim',
'required' => true,
'max' => 256,
],
],
'bodytext' => [
'label' => 'LLL:EXT:blog_example/Resources/Private/Language/locallang_db.xlf:tx_blogexample_domain_model_info.bodytext',
'config' => [
'type' => 'text',
'enableRichtext' => true,
],
],
'post' => [
'config' => [
'type' => 'passthrough',
],
],
],
'types' => [
0 => ['showitem' => '
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
name, bodytext,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
hidden,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
--palette--;;paletteLanguage,
--div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
'],
],
'palettes' => [
'paletteLanguage' => [
'showitem' => 'sys_language_uid, l10n_parent',
],
],
];
Use arbitrary database tables with an Extbase model
It is possible to use tables that do not convey to the naming scheme mentioned in the last section. In this case you have to define the connection between the database table and the file EXT:{ext_key}/Configuration/Extbase/Persistence/Classes.php.
In the following example, the table fe_
provided by the system
extension frontend
is used as persistence table for the model
Administrator
. Additionally the table fe_
is used to persist
the model Frontend
.
<?php
declare(strict_types=1);
use T3docs\BlogExample\Domain\Model\Administrator;
use T3docs\BlogExample\Domain\Model\Blog;
use T3docs\BlogExample\Domain\Model\FrontendUserGroup;
use T3docs\BlogExample\Domain\Model\Post;
return [
Administrator::class => [
'tableName' => 'fe_users',
'recordType' => Administrator::class,
'properties' => [
'administratorName' => [
'fieldName' => 'username',
],
],
],
FrontendUserGroup::class => [
'tableName' => 'fe_groups',
],
Blog::class => [
'tableName' => 'tx_blogexample_domain_model_blog',
'properties' => [
'categories' => [
'fieldName' => 'category',
],
],
],
Post::class => [
'tableName' => 'tx_blogexample_domain_model_post',
'properties' => [
'categories' => [
'fieldName' => 'category',
],
],
],
];
The key record
makes sure that the defined model is only used if the
type of the record is set to
\Friends
. This way the
class will only be used for administrators but not plain frontend users.
The array stored in properties
to match properties to database field
names if the names do not match.
Record types and persistence
It is possible to use different models for the same database table.
A common use case are related domain objects that share common features and should be handled by hierarchical model classes.
In this case the type of the model is stored in a field in the table, commonly
in a field called record_
. This field is then registered as
type
field in the ctrl
section of the TCA array:
return [
'ctrl' => [
'title' => 'Something',
'label' => 'title',
'type' => 'record_type',
// …
],
];
The relationship between record type and preferred model is then configured
in the Configuration/
file.
return [
\MyVendor\MyExtension\Domain\Model\Something::class => [
'tableName' => 'tx_myextension_domain_model_party',
'recordType' => 'something',
'subclasses' => [
'oneSubClass' => \MyVendor\MyExtension\Domain\Model\SubClass1::class,
'anotherSubClass' => MyVendor\MyExtension\Domain\Model\SubClass2::class,
],
],
];
It is then possible to have a general repository, Something
which returns both SubClass1 and SubClass2 objects depending on the value of
the record_
field. This way related domain objects can as one
in some contexts.
Create a custom model for a Core table
This example adds a custom model for the tt_
table. Three steps
are required:
-
Create a model
In this example, we assume that we need the two fields
header
andbodytext
, so only these two fields are available in the model class.<?php declare(strict_types=1); namespace MyVendor\MyExtension\Domain\Model; use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; class Content extends AbstractEntity { protected string $header = ''; protected string $bodytext = ''; public function getHeader(): string { return $this->header; } public function setHeader(string $header): void { $this->header = $header; } public function getBodytext(): string { return $this->bodytext; } public function setBodytext(string $bodytext): void { $this->bodytext = $bodytext; } }
Note
It is not necessary to define a property in the model for each field in the table. Define only the properties for the fields you need!
-
Create the repository
We need a repository to query the data from the table:
-
Connect table with model
Finally, we need to connect the table to the model:
Events
Some PSR-14 events are available: