Typo3 7 Extbase Actions FlexForm - typo3

I using the Typo3 7.6.10 Extbase Builder.
I have a created an extension and a have a model with one controller.
In my controller i have 2 actions. list(); searchbar();
Now i want to choose in the backend when im adding the plugin which action to start! I can't manage to do this option.
I heard about the FlexForm Options and switchableControllerActions.
But i can't manage to do this. The Documentation is bad https://wiki.typo3.org/Extension_Development,_using_Flexforms#Create_Your_Extension
For Example: t3lib_extMgm is deprecated
Is there a valid example how to do this?

Create an .xml file. I know of no convention, but it's a good idea to name the file the same as your plugin, because you need separate files for each plugin type of your extension.
typo3conf/ext/extensionkey/Configuration/FlexForms/Pluginname.xml
The xml file needs to contain at least a TCEform structure with the key switchableControllerActions as a select type option, like so.
<?xml version="1.0" encoding="UTF-8"?>
<T3DataStructure>
<sheets>
<general>
<ROOT>
<TCEforms>
<sheetTitle>Display type</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<switchableControllerActions>
<TCEforms>
<label>Display</label>
<config>
<type>select</type>
<items type="array">
<numIndex index="1" type="array">
<numIndex index="0">List</numIndex>
<numIndex index="1">Controller->list</numIndex>
</numIndex>
<numIndex index="2" type="array">
<numIndex index="0">Search bar</numIndex>
<numIndex index="1">Controller->searchbar</numIndex>
</numIndex>
</items>
</config>
</TCEforms>
</switchableControllerActions>
</el>
</ROOT>
</general>
</sheets>
</T3DataStructure>
Next, make the Flexform known in the Backend by registering the file. Make note of the $pluginSignature variable. It must match the pattern of extension_pluginname. You'll have to define the plugin name accordingly.
// Register FlexForm Configuration
$GLOBALS['TCA']['tt_content']['types']['list']['subtypes_addlist']['extension_plugin'] = 'pi_flexform';
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPiFlexFormValue(
'extension_plugin',
'FILE:EXT:extensionkey/Configuration/FlexForms/Pluginname.xml'
);
In the example above, replace "extension_plugin" and "extensionkey" accordingly.
Lastly, flush the system cache and you should be good to go. The configuration option should turn up in the plugins settings. The switchableControllerActions value defined should then replace your standard action for the plugin instance.
There are, however, a few more things to point out: Note, that the actions you define replaces the allowed cacheableControllerAction combination. So, if your extension has, for extample, another action show() for this plugin instance, that one needs to be appended like so:
<numIndex index="1" type="array">
<numIndex index="0">List</numIndex>
<numIndex index="1">Controller->list;Controller->show</numIndex>
</numIndex>

Related

TYPO3 (7.6.15) Extbase displayCond in flexform.xml not working in one of two extensions

I've been googling quite a bit about this problem but didn't find a mistake.
I've got a quite simple extension I wrote with Extension Builder that works just as intended. But one small mistake remains.
The extension is used for courses and course-applications. These courses are of different types. If I want to add the plugin-element to a page I have two different types of displaying options for the frontend: one is used for the home page, showing the different types of courses, the other is used for the respective course page to list all the courses of that type and a registration form. This all works perfectly. So when I add a plugin-element to the page I can either choose "Home" or "Course page". When Home is selected no further options should show. When "course page" is selected there should be showing another dropdown element with the different course types.
Only recently I realized that in my flexform I had eliminated the displayCond (don't remember why) and of course it shows the option for the course types with "home" and "course page". BUT if I add the displayCond it doesn't show with either option. Here's the flexform-code with the displayCond:
<?xml version="1.0" encoding="UTF-8"?>
<T3DataStructure>
<sheets>
<general>
<ROOT>
<TCEforms>
<sheetTitle>Kurse</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<switchableControllerActions>
<TCEforms>
<label>Ansicht</label>
<onChange>reload</onChange>
<config>
<type>select</type>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="0">Home</numIndex>
<numIndex index="1">Kurse->listHome</numIndex>
</numIndex>
<numIndex index="1" type="array">
<numIndex index="0">Kursseite</numIndex>
<numIndex index="1">Kurse->list;Kunde->sendMail</numIndex>
</numIndex>
</items>
</config>
</TCEforms>
</switchableControllerActions>
<settings.kursTypen>
<TCEforms>
<label>Kurstyp</label>
<config>
<type>select</type>
<foreign_table>tx_gicourses_domain_model_kurstyp</foreign_table>
<foreign_table_where>AND (sys_language_uid=CAST('###REC_FIELD_sys_language_uid###' AS UNSIGNED) OR sys_language_uid = '-1') AND tx_gicourses_domain_model_kurstyp.deleted = 0 AND tx_gicourses_domain_model_kurstyp.hidden = 0 order by name</foreign_table_where>
<size>1</size>
<minitems>1</minitems>
<maxitems>1</maxitems>
</config>
<displayCond>
<OR>
<numIndex index="1">FIELD:switchableControllerActions:=:Kurse->list</numIndex>
</OR>
</displayCond>
</TCEforms>
</settings.kursTypen>
</el>
</ROOT>
</general>
</sheets>
</T3DataStructure>
FUNNY thing is, that in another extension, where I have an according display-condition, this works just as intended:
<?xml version="1.0" encoding="UTF-8"?>
<T3DataStructure>
<sheets>
<general>
<ROOT>
<TCEforms>
<sheetTitle>Books</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<switchableControllerActions>
<TCEforms>
<label>Ansicht</label>
<onChange>reload</onChange>
<config>
<type>select</type>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="0">Alle</numIndex>
<numIndex index="1">Buch->list</numIndex>
</numIndex>
<numIndex index="1" type="array">
<numIndex index="0">Nach Kategorie</numIndex>
<numIndex index="1">Buch->listByCat</numIndex>
</numIndex>
</items>
</config>
</TCEforms>
</switchableControllerActions>
<settings.buchKategorie>
<TCEforms>
<label>Buchkategorie</label>
<config>
<type>select</type>
<foreign_table>tx_gibooks_domain_model_buchkategorie</foreign_table>
<foreign_table_where>AND (sys_language_uid=CAST('###REC_FIELD_sys_language_uid###' AS UNSIGNED) OR sys_language_uid = '-1') AND tx_gibooks_domain_model_buchkategorie.deleted = 0 AND tx_gibooks_domain_model_buchkategorie.hidden = 0 order by name</foreign_table_where>
<size>1</size>
<minitems>1</minitems>
<maxitems>1</maxitems>
</config>
<displayCond>
<OR>
<numIndex index="1">FIELD:switchableControllerActions:=:Buch->listByCat</numIndex>
</OR>
</displayCond>
</TCEforms>
</settings.buchKategorie>
</el>
</ROOT>
</general>
</sheets>
</T3DataStructure>
The only difference that I had in mind was that the action in the first extension (Kurse->list) was a non-cacheable action in comparison to the one in the second extension (Buch->listByCat) which was a cacheable action. But even with changing this nothing changed when selecting the plugin-element.
Where could this problem originate from? Do I have to check something else? Is there another way of achieving the wanted result?
I've read about several similar problems but none of them stated a problem with the code I have (no typo-mistakes, condition is correct..) although I have read about several bugs that had been related to the displayCond which seemed to be resolved though.
As I'm quite new with TYPO3 I would appreciate if you could point me to files which need to be controlled and/or explain your code. Thank you
For the time being I can leave the option showing on both "Home" and "course page" but it might be quite confusing for someone (an editor) who doesn't really like working with computers...
This is half a shot from the hip, but have you tried this without the <OR> segment? Normally you don't need <AND> or <OR> when you have only a single condition to be checked - and I suspect that this is confusing the condition so it gives false positives. Take this with a grain of salt though - I'm not even sure if that displayCond is the right way to check if a string contains another string.
That said, there have been fixes for both FlexForm value resolving/checking and displayCond - so in any case it certainly is worth while to upgrade your TYPO3 version (there have been 7+ bug fix releases since your version).
I found my mistake thanks to Claus Due:
my displayCond before correction:
FIELD:switchableControllerActions:=:Kurse->list
and after:
FIELD:switchableControllerActions:=:Kurse->list;Kunde->sendMail
That's what happens when you copy something that's supposed to work but you don't even understand what it does. Thanks to the hint of Claus Due I realized that this was a comparison of strings and that the compared string didn't match with the wanted one.
So if someone wants do use this for something else: you have to use the whole string of actions after "FIELD:switchableControllerActions:=:"...
Fairly easy isn't it... Happy Coding
I had something similar. My displayCond had no effect. I folwwed the instructions on the TYPO3 Explained tutorial. In the example given the displayCond is placed inside the config tag.
Not working:
<TCEforms>
<label>Label</label>
<config>
<displayCond>FIELD:switchableControllerActions:=:Extension->themes</displayCond>
<type>input</type>
</config>
</TCEforms>
Working:
<TCEforms>
<label>Label</label>
<displayCond>FIELD:switchableControllerActions:=:Extension->themes</displayCond>
<config>
<type>input</type>
</config>
</TCEforms>
How does the "Kurse->list" look in the Flexform XML? It should read there "Kurse->list" else you probably have a tag mismatch

Use php array to loop in TYPO3 flex type

I'm building an extension and I have a field of type flex. I have an array with extracted records from a TS config that I like to use as prefilled values for a field, which I also want to be editable in the TYPO3 admin. So I want them to be shown as textarea, however I don't know how to use the array in the flex items configuration.
'<T3DataStructure>
<meta>
<langDisable>1</langDisable>
</meta>
<sheets>
<sDEF>
<ROOT>
<TCEforms>
<sheetTitle>Title</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<pageSelector>
<TCEforms>
<label>Something</label>
<config>
<type>text</type>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="0">'.$php_variable_array.'</numIndex>
<numIndex index="1">0</numIndex>
</numIndex>
</items>
<minitems>0</minitems>
<maxitems>1</maxitems>
</config>
</TCEforms>
</pageSelector>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>'

switchable controller action is not working TYPO3 7.6

Hi I have an extension in TYPO3 7.6. I have two actions list and show. In my flexform there is a switchable controller action.list action is working. But show action not working. Please check my code.
Flexform
<switchableControllerActions>
<TCEforms>
<label>Display Type</label>
<onChange>reload</onChange>
<config>
<type>select</type>
<items type="array">
<numIndex index="1" type="array">
<numIndex index="0">List</numIndex>
<numIndex index="1">News->list</numIndex>
</numIndex>
<numIndex index="2" type="array">
<numIndex index="0">Detail</numIndex>
<numIndex index="1">News->show</numIndex>
</numIndex>
</items>
<minitems>0</minitems>
<maxitems>1</maxitems>
<size>1</size>
</config>
</TCEforms>
</switchableControllerActions>
list view
<f:if condition="{news}">
<ul>
<f:for each="{news}" as="item">
<li>
<f:link.action action="show" controller="News" arguments="{news:'{item}'}" noCacheHash="false" pageUid="{settings.detailPid}" >
{item.title}
</f:link.action>
</li>
</f:for>
</ul>
</f:if>
I selected list from configuration in list page and select detail from detail page. List is working perfectly but detail is not working.
Try to add arguments like this:
arguments="{news: item.uid}"
in showAction you can get argument like this:
$newsId = $this->request->getArgument('news');
$news = $this->newsRepository->findByUid($newsId);
$this->view->assign('news', $news);
It will work perfectly as you required.
Not gtting any error message.only a blank page is shown
You might want to change that first
check your error_reporting on php level (display_errors)
set your Environment to Development (you can select the preset in the install tool)
Look Debug options up in the install tool (all configuration)
Keep in mind, that you dont want to make those adjustments in Production Environment.
Then you should be able to see the error.
I selected list from configuration in list page and select detail from
detail page. List is working perfectly but detail is not working.
Did you add the show action to the plugin configuration? Look that up in your extensions ext_localconf.php
Look for this call:
ExtensionUtility::configurePlugin
Your Controller->action combinations have to exist in the first array parameter you pass. That might look like:
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'Vendor.ext_key',
'News',
array(
'News' => 'list,show'
)
);
If you pass a 4th parameter with Controller->action combinations (like the other), you can define actions, that should not be cached. You would use such to configure form actions or filterable result-lists.
note: Allways use the full namespace in ext_localconf.php and other bootstrap files, if you make use of "use" statements you might have another fatal error, typo3 concatenates all those bootstrap files.
Also - you could have misunderstood the switchableControllerActions pattern. If you want one plugin (the ce) to show both actions, the option has to be
<switchableControllerActions>
<TCEforms>
...
<config>
<type>select</type>
<items type="array">
...
<numIndex index="3" type="array">
<numIndex index="0">List with Details</numIndex>
<numIndex index="1">News->list;News->show</numIndex>
</numIndex>
</items>
...
</config>
</TCEforms>
</switchableControllerActions>
The selected option will be saved in the xml datastructure and is used as configuration, so if only one action is available for this instance then you will receive an error.
If you use different content elements to show the list and detail view you have to select the correct switchableControllerAction option in both content elements.

Typo3 flexform: choose tt_content element from specific page only

I need to create a flexform field where the user is able to select a tt_content element - but I want to limit that to only tt_content elements from a certain page. What I have so far:
<settings.test>
<TCEforms>
<label>test</label>
<config>
<type>group</type>
<internal_type>db</internal_type>
<allowed>tt_content</allowed>
<size>1</size>
<maxitems>1</maxitems>
<minitems>0</minitems>
<show_thumbs>1</show_thumbs>
</config>
</TCEforms>
</settings.test>
is there a way to limit it to a specific page? The typo3 Version is 7.6.10.
Thank you in advance.
The <type>group</type> is used for a browselike behavior and i can not see how you can add a filter there. Since you want to show a limited number of elements, you can use <type>select</type> with foreign_table_where
<config>
<type>select</type>
<renderType>selectSingle</renderType>
<foreign_table>tt_content</foreign_table>
<foreign_table_where>AND tt_content.pid = ###PAGE_TSCONFIG_ID###</foreign_table_where>
<size>1</size>
<items>
<numindex index="0">
<numindex index="0">--</numindex>
<numindex index="1"></numindex>
</numindex>
</items>
<maxitems>1</maxitems>
<minitems>0</minitems>
</config>
Then you need to set the id in your Page Config
TCEFORM.tt_content.pi_flexform.PAGE_TSCONFIG_ID = 123

TYPO3 Extbase switchableControllerActions

I have the own extension that has controller with two actions: listAction and showAction.
Question: Can I display two actions at the same page.
At specific page I've created an insert plugin record with my own plugin where in flexform of backend configuration of the plugin I've choosen "list action" via switchableControllerActions field. The list action contains list of products with link to the show action of product.
So what do I want?
F.e.
I have page Products. The URL is example.com/products (here is my list action)
And for show action I want the URL like example.com/products/name-of-product
I've found a extension with this functionality. It's gb_events. And I noticed that in switchableControllerActions field of flexform of plugin there is something like this:
<switchableControllerActions>
<TCEforms>
<label>LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions</label>
<config>
<type>select</type>
<items type="array">
<numIndex index="0" type="array">
<numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.upcoming</numIndex>
<numIndex index="1">Event->upcoming;Event->list;Event->calendar;Event->show;Event->export</numIndex>
</numIndex>
<numIndex index="1" type="array">
<numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.list</numIndex>
<numIndex index="1">Event->list;Event->upcoming;Event->calendar;Event->show;Event->export</numIndex>
</numIndex>
<numIndex index="2" type="array">
<numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.calendar</numIndex>
<numIndex index="1">Event->calendar;Event->upcoming;Event->list;Event->show;Event->export</numIndex>
</numIndex>
<numIndex index="3" type="array">
<numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.details</numIndex>
<numIndex index="1">Event->show;Event->list;Event->upcoming;Event->calendar;Event->export</numIndex>
</numIndex>
</items>
<maxitems>1</maxitems>
<size>1</size>
</config>
<onChange>reload</onChange>
</TCEforms>
</switchableControllerActions>
I've updated my flexform configuration. But it still doesn't work. I've the same list view after when I click on link with show action.
Thanks in advance. I will appreciate any help.
The structurally more sensical approach is to keep that sort of logic inside the controller.
Make your showAction the defaut one and check the arguments in its initializaion. If no product was given, or the specified one cannot be loaded, forward to the list action.
/**
* initialize action show
* #return void
*/
public function initializeShowAction() {
if($this->request->hasArgument('product')){
if( $product=$this->stadtRepository->findByUid(
intval($this->request->getArgument('product'))
) ){
$this->request->setArgument('product',$product);
return;
}
}
$this->forward('list');
}
Make sure you have both, the list and detail Action in your switchableControllerActions like so:
<numIndex index="0" type="array">
<numIndex index="0">LLL:EXT:gb_events/Resources/Private/Language/locallang_db.xlf:flexform.default.switchableControllerActions.upcoming</numIndex>
<numIndex index="1">Event->list;Event->calendar;Event->show</numIndex>
</numIndex>
Then in your TypoScript Template use a condition to set the Controller / Action based on a detail uid:
[globalVar = GP:tx_myext_plugin|showUid > 0]
config.defaultGetVars {
tx_myext_plugin.action = show
}
[global]
To get the other controller parameter off the URL in RealUrl use something like this:
array(
'GETvar' => 'tx_extkey_plugin[action]',
'noMatch' => 'bypass'
),
You can find more about this trick in this german article here