Overwrite TCEFORM from Extension Flexform - typo3

I'm using TYPO3 8.7.1 and want to overwrite a flexform field with TCEFORM in PageTS.
The file locallang_db.xlf has the following entry:
<trans-unit id="section.title" xml:space="preserve" approved="yes">
<source>Section</source><target state="translated">Title</target>
</trans-unit>
The following snippet is from my flexform file:
<numIndex index="1" type="array">
<numIndex index="0">LLL:EXT:h_test/Resources/Private/Language/locallang_db.xlf:section.title</numIndex>
<numIndex index="1">value</numIndex>
</numIndex>
I've now tried different variations to overwrite this:
TCEFORM.tt_content.pi_flexform.tx_htest.section.title = New Title
Or this:
TCEFORM.tt_content.pi_flexform.h_test.section.title = New Title
And much more, but none is working. Any help or hint is really appreciated!

You must include the sheetname of the flexform you want to override. See the TSConfig reference for more details.
The next examples show, how to override flexform labels for the TYPO3 extension sf_event_mgt and the plugin Pievent. Note, that the dataStructKey is a combination of the extension key and the pluginname (in this example sfeventmgt_pievent)
Example 1 - override label for field switchableControllerActions
TCEFORM.tt_content.pi_flexform.sfeventmgt_pievent.sDEF.switchableControllerActions.label = Overwritten Label
Example 2 - override label for field settings.queryLimit
TCEFORM.tt_content.pi_flexform.sfeventmgt_pievent.sDEF.settings\.queryLimit.label = Overwritten Label
If the field to override includes a dot, the dot must be escaped with a \ as shown in example 2.

Related

Typo3 Custom Element with Flexform: How do I write value to tt_content header?

I am writing a Typo3 extension with custom content elements using Flexforms. All is working fine.
I just would like to add a value to "header" inside of tt_content just like the standard Typo3 content elements do. That way, if I create a translation, the default header of the translated content should show as "My headline (copy 1)" and not just as "(copy 1)". Also, the header should show up if I try and add an anchor link to the element.
For example, my flexform starts like this:
<T3DataStructure>
<sheets>
<sGeneral>
<ROOT>
<TCEforms>
<sheetTitle>My Element</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<headline>
<TCEforms>
<label>Text</label>
<config>
<type>input</type>
</config>
</TCEforms>
</headline>
...
I access above headline value in my HTML template like this: {flexform.sGeneral.headline}
That works well. How can I accomplish that this value also gets written to tt_content header?
I really appreciate your help.
The flexform (and all fields declared inside) are one field of the whole tt_content record. So there is a big difference whether you access a flexform field data or a data from any regular field in the record. You can't mix it up. (A field header in your flexform has no relation to the regular field header of the record)
For giving editors access to the regular header field you need to declare access for your type of tt_content (CType). This is done in the TCA-declaration.
Anyway you should have access to the header field from your FLUID as you have access to the whole tt_content record. normaly as {data.fieldname}, you might inspect with the debugger:
<f:debug title="all fluid variables">{_all}</f:debug>

How to get TCEFORM in a hook to read altLabels of a dropdown of another extension

I have a hook and try to get a dropdown label text of an other extension. How can i get the flexform typoscript with that values?
Get the TypoScript config with the BackendUtility and look in the TCEFORM of the desired extension:
$pageTs = \TYPO3\CMS\Backend\Utility\BackendUtility::getPagesTSconfig(1);
$typeLabels = $pageTs['TCEFORM.']['tx_news_domain_model_news.']['type.']['altLabels.'];

TYPO3 GeneralStorageFolder is gone, how to get storagePID inside plugin-flexform?

Good morning
In TYPO3 7.4 the "General Storage Folder" was kicked. Before this you could use the General Storage Folder inside a plugin-flexform. You could do things like
<settings.type>
<TCEforms>
<label>Betriebsart</label>
<config>
<type>select</type>
<items type="array"></items>
<allowNonIdValues>1</allowNonIdValues>
<multiple>1</multiple>
<maxitems>99</maxitems>
<minitems>0</minitems>
<size>10</size>
<foreign_table>tx_enzhotellist_domain_model_type</foreign_table>
<foreign_label>name</foreign_label>
<foreign_table_where>AND sys_language_uid = 0 AND tx_enzhotellist_domain_model_type.pid=###STORAGE_PID###</foreign_table_where>
</config>
</TCEforms>
</settings.type>
It was possible to access the values inside General Storage Folder with help of ###STORAGE_PID###. But now this way is gone, kicked off, obsolete, whatever... Sad - really sad.
So I ask you, how to access storagePid inside plugin-flexform? (btw: typoscript-settings do not help here!)
kind regards
Johannes
You don't get this field back as it has been removed. However you can use multiple other ways, described in the manual.
###CURRENT_PID### - is the current page id (pid of the record).
###SITEROOT###
###PAGE_TSCONFIG_ID### - a value you can set from Page TSconfig dynamically.
###PAGE_TSCONFIG_IDLIST### - a value you can set from Page TSconfig dynamically.
###PAGE_TSCONFIG_STR### - a value you can set from Page TSconfig dynamically.

TYPO3 Flexforms: Access previous set value

I'd like to display forms per agency. To achieve this, I want to select one agency on the frontend plugin (with a flexform) and then, when I have chosen one, the flexform reloads with<onChange>reload</onChange> so I get the filtered records.
Problem
How can I access flexform-values in another select-block? My general idea is to use the <foreign_table_where></foreign_table_where> part to limit this. But I cant access previous set values (unlike I do it in the <displayCond></displayCond> block with FIELD:mySetting). My form-part looks like this:
Form
<config>
<type>select</type>
<foreign_table>foreignTableForm</foreign_table>
<foreign_table_where>HOW TO DO?</foreign_table_where>
<minitems>0</minitems>
<maxitems>10</maxitems>
<multiple>0</multiple>
<size>5</size>
<itemListStyle>Width:250px</itemListStyle>
</config>
Agency
<config>
<type>select</type>
<foreign_table>foreignTableAgency</foreign_table>
<minitems>0</minitems>
<maxitems>10</maxitems>
<multiple>0</multiple>
<size>5</size>
<itemListStyle>Width:250px</itemListStyle>
</config>
Goal
Get values from agency foreign table (works)
As I have clicked on that specific agency, the flexform reloads (works)
Only those forms get listed, which have the foreign key equal to the agency's uid previously set after the reload (how to achieve this?)
Thanks for any help!
You need to use a hook to modify the flexform in the fly. Please check ext:news on how to archive this. It does something similar to trim the flexform to only show valid field in the current selected context.

Only show single item by flexform in Extbase

I created a small extension that can show a puzzle game. The switchable controller actions I made include list/show (works fine), admin (also fine) and show only.
For show only I want to select a database entry from the flexform which will then be shown by the single view. For that I added a new field to the flexform:
<settings.singlePuzzle>
<TCEforms>
<label>Puzzle to show</label>
<config>
<type>select</type>
<foreign_table>tx_wspuzzle_domain_model_puzzle</foreign_table>
<items>
<numIndex index="0" type="array">
<numIndex index="0">-- Choose --</numIndex>
<numIndex index="1"></numIndex>
</numIndex>
</items>
<size>1</size>
<maxitems>1</maxitems>
<minitems>0</minitems>
</config>
</TCEforms>
</settings.singlePuzzle>
So far so good, if I select an item here and debug it in the list view it seems to select the correct id.
Now I changed the showAction in the controller to look like this:
/**
* action show
*
* #param \Websafari\Wspuzzle\Domain\Model\Puzzle $puzzle
* #return void
*/
public function showAction(\Websafari\Wspuzzle\Domain\Model\Puzzle $puzzle = NULL) {
if(is_null($puzzle)) $puzzle = $this->puzzleRepository->findByUid($this->settings['singlePuzzle']);
$this->view->assign('puzzle', $puzzle);
}
So now I change the action to "show only", select an entry for "singlePuzzle" and then (I think) I should be good to go, but all I get ist the following error:
Required argument "puzzle" is not set.
Obviously I made a mistake, but I don't get it.
First: Why is "puzzle" still required? That's why I added "= NULL" to the function (I also tried adding #ignorevalidation $puzzle to the comment).
Second: Why is it not set? When I debug "$this->settings['singlePuzzle'];" I get an id for a puzzle object.
Would be great if someone could point out my error, because I'm really stuck here. Thnx a lot!
The problem is that the reflection information of a class (arguments etc.) are cached in Extbase. So if you change the definition and don't clear the respective cache, it still will require your argument.
You need to clear the "System caches" in TYPO3. There are three ways to do it:
If you are in development context, you will have the button (with the red flash icon) in the backend.
You can enable the button through User TSconfig in production context using options.clearCache.system = 1.
A button for clearing the system cache is in the install tool, section "Important actions".
You can also manually clear all cache related tables in PhpMyAdmin
TRUNCATE table cf_cache_hash;
TRUNCATE table cf_cache_hash_tags;
TRUNCATE table cf_cache_pages;
TRUNCATE table cf_cache_pagesection;
TRUNCATE table cf_cache_pagesection_tags;
TRUNCATE table cf_cache_pages_tags;
TRUNCATE table cf_cache_rootline;
TRUNCATE table cf_cache_rootline_tags;
TRUNCATE table cf_extbase_object;
TRUNCATE table cf_extbase_object_tags;
TRUNCATE table cf_extbase_reflection;
TRUNCATE table cf_extbase_reflection_tags;
TRUNCATE cf_extbase_typo3dbbackend_queries;
TRUNCATE cf_extbase_typo3dbbackend_queries_tags;
TRUNCATE cf_extbase_typo3dbbackend_tablecolumns;
TRUNCATE cf_extbase_typo3dbbackend_tablecolumns_tags;
TRUNCATE cf_extbase_datamapfactory_datamap;
TRUNCATE cf_extbase_datamapfactory_datamap_tags;
This also truncates query cache etc. what can be useful in some situation.
As soon as the cache is cleared, it should work.
BTW, just to be on the safe side, you should typecast the UID from FlexForm:
if(is_null($puzzle)) $puzzle = $this->puzzleRepository->findByUid((int)$this->settings['singlePuzzle']);