Get sys_categories from tt_content flexform settings - typo3

Let's say I have a FE Plugin with the option to set some sys_category references via the following flexform field:
<settings.categories>
<TCEforms>
<label>Some Label</label>
<config>
<type>select</type>
<foreign_table>sys_category</foreign_table>
<foreign_table_where> AND sys_category.sys_language_uid IN (-1, 0) ORDER BY sys_category.sorting ASC</foreign_table_where>
<MM>sys_category_record_mm</MM>
<MM_opposite_field>items</MM_opposite_field>
<MM_match_fields>
<tablenames>tt_content</tablenames>
<fieldname>categories</fieldname>
</MM_match_fields>
<maxitems>9999</maxitems>
<renderMode>tree</renderMode>
<size>10</size>
<treeConfig>
<appearance>
<expandAll>1</expandAll>
<showHeader>1</showHeader>
</appearance>
<parentField>parent</parentField>
</treeConfig>
</config>
</TCEforms>
</settings.categories>
Now I want to get all category Objects referenced in the flexform in the controller of the plugin. What's the best approach to do so? Should’nt there already be a suitable repository function somewhere? Thank you for your help!

There is no dedicated API for that, however normally you wouldn't need the mm-relation. Removing that and having it like
<settings.categories>
<TCEforms>
<label>LLL:EXT:news/Resources/Private/Language/locallang_be.xlf:flexforms_general.categories</label>
<config>
<type>select</type>
<renderMode>tree</renderMode>
<renderType>selectTree</renderType>
<treeConfig>
<dataProvider>GeorgRinger\News\TreeProvider\DatabaseTreeDataProvider</dataProvider>
<parentField>parent</parentField>
<appearance>
<maxLevels>99</maxLevels>
<expandAll>TRUE</expandAll>
<showHeader>TRUE</showHeader>
<width>600</width>
</appearance>
</treeConfig>
<foreign_table>sys_category</foreign_table>
<foreign_table_where>AND (sys_category.sys_language_uid = 0 OR sys_category.l10n_parent = 0) ORDER BY sys_category.sorting</foreign_table_where>
<size>15</size>
<minitems>0</minitems>
<maxitems>99</maxitems>
</config>
</TCEforms>
</settings.categories>
it is much easier to retrieve the categories. You can also take a look at the CategoryRepository I am using for the news extension https://github.com/georgringer/news/blob/master/Classes/Domain/Repository/CategoryRepository.php

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

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.

Render multitype link field via fluid - TYPO3

What is the best way to render link field in TYPO3 fluid template?
Link field is defined via flexform as:
<field_link type="array">
<TCEforms type="array">
<config type="array">
<type>input</type>
<eval>trim</eval>
<wizards type="array">
<link type="array">
<type>popup</type>
<title>Link</title>
<icon>link_popup.gif</icon>
<script>
browse_links.php ? mode = wizard & amp;
act = page
</script>
<params type="array">
<blindLinkOptions>file,spec,email,folder</blindLinkOptions>
</params>
<JSopenParams>height=300,width=500,status=0,menubar=0,scrollbars=1</JSopenParams>
</link>
</wizards>
</config>
<label>link</label>
</TCEforms>
</field_link>
Fluid comes with viewhelpers such as link.email, link.external, link.page but my link field could be either page id or external link or email or link to sys_file record. How do you handle that in your projects without making multiple if statemens in fluid template? (custom viewhelper?, typoscript object)?
You can also use the f:link.page to generate links external urls or files, that does not matter as internally typolink is used.
If you are using the wizards like in your example, you should use the f:link.typolink viewhelper which supports all attributes.
Link for email works perfect
here my flexform:
<settings.link>
<TCEforms>
<label>Link</label>
<config>
<type>input</type>
<size>30</size>
<eval>trim</eval>
<softref>typolink,typolink_tag,images,url</softref>
<wizards>
<_PADDING>2</_PADDING>
<link>
<type>popup</type>
<title>Link</title>
<module>
<name>wizard_element_browser</name>
<urlParameters>
<mode>wizard</mode>
</urlParameters>
</module>
<icon>link_popup.gif</icon>
<script>browse_links.php?mode=wizard</script>
<params>
<blindLinkOptions>file,folder,url,spec</blindLinkOptions>
</params>
<JSopenParams>height=500,width=500,status=0,menubar=0,scrollbars=1</JSopenParams>
</link>
</wizards>
</config>
</TCEforms>
</settings.link>
Output:
Liunk

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

TCA (flexform) multi select

I work on an extension and for a plugin I want to select specific records. For that I created a flexform with a TCA select configuration:
<T3DataStructure>
<meta>
<langDisable>1</langDisable>
</meta>
<sheets>
<sDEF>
<ROOT>
<TCEforms>
<sheetTitle>TEST</sheetTitle>
</TCEforms>
<type>array</type>
<el>
<settings.selection>
<TCEforms>
<exclude>1</exclude>
<label>Selection</label>
<config>
<type>select</type>
<foreign_table>tx_mycollection_domain_model_mycollection</foreign_table>
<renderType>selectCheckBox</renderType>
<size>5</size>
<minItems>3</minItems>
<maxItems>999</maxItems>
<foreign_table_where>AND tx_mycollection_domain_model_mycollection.sys_language_uid=###REC_FIELD_sys_language_uid###</foreign_table_where>
</config>
</TCEforms>
</settings.selection>
</el>
</ROOT>
</sDEF>
</sheets>
</T3DataStructure>
It looks fine, in the backend I have checkboxes to select the records. But when I save the plugin only the first checkbox is checked/saved.
Is there something wrong in the configuration or what could be the reason that I can not save multible values?
<minItems>3</minItems>
<maxItems>999</maxItems>
From the documentation here:
https://docs.typo3.org/typo3cms/TCAReference/Reference/Columns/Select/Index.html#properties
These needs to be specified as all lower case, so changing them to:
<minitems>3</minitems>
<maxitems>999</maxitems>
Should resolve your issue. It is saving only 1 right now, since maxitems by default is set to 1.