Attention
TYPO3 v10 has reached end-of-life as of April 30th 2023 and is no longer being maintained. Use the version switcher on the top left of this page to select documentation for a supported version of TYPO3.
Need more time before upgrading? You can purchase Extended Long Term Support (ELTS) for TYPO3 v10 here: TYPO3 ELTS.
Database: DataHandler Basics (Formerly Known as TCEmain)¶
When you are using TCE from your backend applications you need to
prepare two arrays of information which contain the instructions to
DataHandler (\TYPO3\CMS\Core\DataHandling\DataHandler
)
of what actions to perform. They fall into two categories:
data and commands.
"Data" is when you want to write information to a database table or create a new record.
"Commands" is when you want to move, copy or delete a record in the system.
The data and commands are created as multidimensional arrays and to understand the API of DataHandler you simply need to understand the hierarchy of these two arrays.
Caution
The DataHandler needs a properly configured TCA. If your field is not configured in the TCA the DataHandler will not be able to interact with it. This also is the case if you configured "type"="none" (which is in fact a valid type) or if an invalid type is specified. In that case the DataHandler is not able to determine the correct value of the field.
Commands Array¶
Syntax:
$cmd[ tablename ][ uid ][ command ] = value
Description of keywords in syntax:
Key |
Data type |
Description |
---|---|---|
tablename |
string |
Name of the database table. Must be configured in |
uid |
integer |
The UID of the record that is manipulated. This is always an integer. |
command |
string (command keyword) |
The command type you want to execute. Note Only one command can be executed at a time for each record! The first command in the array will be taken. See table below for command keywords and values |
value |
mixed |
The value for the command See table below for command keywords and values |
Command Keywords and Values¶
Command |
Data type |
Value |
---|---|---|
copy |
integer |
The significance of the value depends on whether it is positive or negative:
|
move |
integer |
Works like "copy" but moves the record instead of making a copy. |
delete |
1 |
Value should always be "1" This action will delete the record (or mark the record "deleted" if
configured in |
undelete |
1 |
Value should always be "1". This action will set the deleted-flag back to 0. |
localize |
integer |
Value is an uid of the Requirements for a successful localization is this:
Apart from this, ordinary permissions apply as if the user wants to make a copy of the record on the same page. The |
copyToLanguage |
integer |
It behaves like The |
inlineLocalizeSynchronize |
array |
Performs localization or synchronization of child records. The command structure is like: $cmd['tt_content'][13]['inlineLocalizeSynchronize'] = [ // 13 is a parent record uid
'field' => 'tx_myfieldname', // field we want to synchronize
'language' => 2, // uid of the target language
// either the key 'action' or 'ids' must be set
'action' => 'localize' // or 'synchronize'
'ids' => [1, 2, 3] // array of child-ids to be localized
]
|
version |
array |
Versioning action. Keys:
|
Examples of Commands:¶
$cmd['tt_content'][54]['delete'] = 1; // Deletes tt_content record with uid=54
$cmd['tt_content'][1203]['copy'] = -303; // Copies tt_content uid=1203 to the position after tt_content uid=303 (new record will have the same pid as tt_content uid=1203)
$cmd['tt_content'][1203]['copy'] = 400; // Copies tt_content uid=1203 to first position in page uid=400
$cmd['tt_content'][1203]['move'] = 400; // Moves tt_content uid=1203 to the first position in page uid=400
Data Array¶
Syntax:
$data[tablename][uid][fieldname] = value
Description of keywords in syntax:
Key |
Data type |
Description |
---|---|---|
tablename |
string |
Name of the database table. Must be configured in |
uid |
mixed |
The UID of the record that is modified. If the record already exists, this is an integer. If you're creating new records, use a random string prefixed with |
fieldname |
string |
Name of the database field you want to set a value for. Must be
configured in |
value |
string |
Value for "fieldname". For fields of type |
Note
For FlexForms the data array of the FlexForm field is deeper than three levels. The number of possible levels for FlexForms is infinite and defined by the data structure of the FlexForm. But FlexForm fields always end with a "regular value" of course.
Examples of Data Submission¶
This creates a new page titled "The page title" as the first page inside page id 45:
$data['pages']['NEW9823be87'] = [
'title' => 'The page title',
'subtitle' => 'Other title stuff',
'pid' => '45'
];
This creates a new page titled "The page title" right after page id 45 in the tree:
$data['pages']['NEW9823be87'] = [
'title' => 'The page title',
'subtitle' => 'Other title stuff',
'pid' => '-45'
];
This creates two new pages right after each other, located right after the page id 45:
$data['pages']['NEW9823be87'] = [
'title' => 'Page 1',
'pid' => '-45'
];
$data['pages']['NEWbe68s587'] = [
'title' => 'Page 2',
'pid' => '-NEW9823be87'
];
Notice how the second "pid" value points to the "NEW..." id placeholder of the first record. This works because the new id of the first record can be accessed by the second record. However it works only when the order in the array is as above since the processing happens in that order!
This creates a new content record with references to existing and one new system category:
$data['sys_category']['NEW9823be87'] = [
'title' => 'New category',
'pid' => 1,
];
$data['tt_content']['NEWbe68s587'] = [
'header' => 'Look ma, categories!',
'pid' => 45,
'categories' => [
1,
2,
'NEW9823be87', // You can also use placeholders here
],
];
Note
To get real uid of the record you have just created use DataHandler's substNEWwithIDs
property like: $uid = $dataHandler->substNEWwithIDs['NEW9823be87'];
This updates the page with uid=9834 to a new title, "New title for this page", and no_cache checked:
$data['pages'][9834] = [
'title' => 'New title for this page',
'no_cache' => '1'
];
Clear Cache¶
TCE also has an API for clearing the cache tables of TYPO3:
Syntax:
$dataHandler->clear_cacheCmd($cacheCmd);
$cacheCmd values |
Description |
---|---|
[integer] |
Clear the cache for the page id given. |
"all" |
Clears all cache tables ( Only available for admin-users unless explicitly allowed by User TSconfig "options.clearCache.all". |
"pages" |
Clears all pages from Only available for admin-users unless explicitly allowed by User TSconfig "options.clearCache.pages". |
Clear cache using cache tags¶
Every processing of data or commands is finalized with flushing a few caches in the pages
group. Cache tags are used to specifically flush the the relevant cache entries instead of the cache as whole.
By default the following cache tags are flushed:
The table name of the updated record, e.g.
pages
when updating a page ortx_myextension_mytable
when updating a record of this table.A combination of table name and record UID, e.g.
pages_10
when updating the page with UID 10 ortx_myextension_mytable_20
when updating the record with UID 20 of this table.A page UID prefixed with
pageID_
(pageId_<page-uid>
), e.g.pageId_10
when updating a page with UID 10 (additionally all related pages, see clearCache_pageGrandParent and clearCache_pageSiblingChildren) andpageId_10
when updating a record if a record of any table placed on the page with UID 10 (<table>.pid = 10
) is updated.
Notice that you can also use the TypoScriptFrontendController::addCacheTags()
method to register additional tags for the cache entry of the current page while it is rendered. This way you can implement an elaborate caching behavior which ensures that every record update in the TYPO3 backend (which is processed by the DataHandler
) automatically flushes the cache of all pages where that record is displayed.
Following the rules mentioned above you could register cache tags from within your Extbase plugin (e.g. controller or a custom viewhelper):
public function __construct(TypoScriptFrontendController $frontendController)
{
$this->frontendController = $frontendController;
}
public function showAction(ExampleModel $example): ResponseInterface
{
// ...
$this->frontendController->addCacheTags([
sprintf('tx_myextension_example_%d', $example->getUid()),
]);
}
Hook for Cache Post-processing¶
You can configure cache post-processing with a user defined PHP
function. Configuration of the hook can be done from
ext_localconf.php
. An example might look like:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['clearCachePostProc'][] = \Vendor\Package\Hook\DataHandlerHook::class . '->postProcessClearCache';
Flags in DataHandler¶
There are a few internal variables you can set prior to executing commands or data submission. These are the most significant:
Internal variable |
Data type |
Description |
---|---|---|
->deleteTree |
Boolean |
Sets whether a page tree branch can be recursively deleted. If this is set, then a page is deleted by deleting the whole branch under it (user must have delete permissions to it all). If not set, then the page is deleted only if it has no branch. Default is false. |
->copyTree |
Integer |
Sets the number of branches on a page tree to copy. If Default is zero. |
->reverseOrder |
Boolean |
If set, the data array is reversed in the order, which is a nice thing if you're creating a whole bunch of new records. Default is zero. |
->copyWhichTables |
list of strings (tables) |
This list of tables decides which tables will be copied. If empty then none will. If "*" then all will (that the user has permission to of course). Default is "*". |