Typo3 9.5 prefill form field with get parameter - forms

I use TYPO3 system extension "form" and want to prefill an input field with a GET parameter.
This TYPO3 8.7. Form prefill input field is working, but only is no_cache=1. Is there another solution without deactivate the whole cache?
Thanks
david

Yes, you can but you need to create HOOK.
This is described in the documentation
For example, the HOOK
/**
* #param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
* #return void
*/
public function initializeFormElement(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
{
if ($renderable->getUniqueIdentifier() === 'contactForm-text-1') {
$renderable->setDefaultValue('foo');
}
}
And the connect the hook
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][<useATimestampAsKeyPlease>]
= \VENDOR\YourNamespace\YourClass::class;
Please, read the documentation for "Form framework".
I did it and get results what I need.

You can disable the cache of the content column of your form page, for example:
lib.content = COA
lib.content{
10 < styles.content.get
}
[page["uid"] == 512]
lib.content = COA_INT
[global]

Thanks TYPO3UA for you answer. But you should use the hook 'afterBuildingFinished' because the 'initializeFormElement' hook is executed BEFORE the properties from the form definition are set in the form element. So the default values from the form definition (even it is an empty string) will override the values set in the initializeFormElement' hook.
See: https://forge.typo3.org/issues/82615
So this works for setting the default value of an form element:
/**
* #param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
* #return void
*/
public function afterBuildingFinished(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
{
if (method_exists($renderable, 'getUniqueIdentifier') && $renderable->getUniqueIdentifier() === 'contactForm-text-1') {
$renderable->setDefaultValue('Value');
}
}
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterBuildingFinished'][<useATimestampAsKeyPlease>]
= \VENDOR\YourNamespace\YourClass::class;

Related

TYPO3 v11 persistence.storagePid is ignored

I have an TYPO3 Extbase extension with TYPO3 11.
My problem is, that every item is shown.
In my plugin there is a Flexform Field for the storagePid. But the plugin completely ignored this settings and every time lists all items.
How can I tell my extension that it should only load items from the selected page?
I have tried to set this:
public function getItems()
{
$table = 'TABLE';
$query = $this->itemRepository->createQuery();
$query->getQuerySettings()->setRespectStoragePage(true);
return $query->execute();
}
But that doesn't help.
This doesn't change anything in the repository
public function initializeObject() {
/** #var Typo3QuerySettings $querySettings */
$querySettings = GeneralUtility::makeInstance(Typo3QuerySettings::class);
$querySettings->setRespectStoragePage(TRUE);
$this->setDefaultQuerySettings($querySettings);
}
I am assuming you mean what you set in the default field tt_content.pages and tt_content.recursive.
Here is an example how to get the page IDs from the fields: https://github.com/TYPO3/typo3/blob/11.5/typo3/sysext/felogin/Classes/Controller/AbstractLoginFormController.php#L35-L50
And then you would set that for your Extbase query:
$querySettings = $this->myRepository->createQuery()->getQuerySettings();
$querySettings->setStoragePageIds(...);
Background:
Here is a great write-up how naming a Flexform field persistence.storagePid would give you that, too https://www.derhansen.de/2016/02/how-extbase-determines-storagepid.html

How to access the ext_conf_template.txt (extension configuration) in typoscript?

There are a few settings in the ext_conf_template.txt in my extension.
I want to check the value of one of these settings, but in typoscript, not in PHP.
In PHP it works like this:
unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['myExt'])
How should I do this in typoscript?
Thanks to the answer of Marcus I was able to get a extension configuration setting into typoscript. First create the extension setting in ext_conf_template.txt:
# cat=Storage; type=string; label=storageFolderPid
storageFolderPid = 1
In ext_local_conf.php add the following lines:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScriptConstants(
"plugin.tx_extensionname.settings.storageFolderPid = ".$GLOBALS['TYPO3_CONF_VARS']['EXTENSIONS']['extension']['storageFolderPid']
);
Then you can use this variabele in your typosript, for instance to create a submenu of a storage folder:
lib.submenu = CONTENT
lib.submenu {
table = tx_extension_domain_model_article
select {
pidInList = {$plugin.tx_extensionname.settings.storageFolderPid}
selectFields = tx_extensionname_domain_model_article.*
}
...
}
I did something similar in my code snippet extension (see complete code on Github), where I just added a custom TypoScript condition:
[DanielGoerz\FsCodeSnippet\Configuration\TypoScript\ConditionMatching\AllLanguagesCondition]
// some conditional TS
[global]
The condition implementation is quite simple:
namespace DanielGoerz\FsCodeSnippet\Configuration\TypoScript\ConditionMatching;
use DanielGoerz\FsCodeSnippet\Utility\FsCodeSnippetConfigurationUtility;
use TYPO3\CMS\Core\Configuration\TypoScript\ConditionMatching\AbstractCondition;
class AllLanguagesCondition extends AbstractCondition
{
/**
* Check whether allLanguages is enabled
* #param array $conditionParameters
* #return bool
*/
public function matchCondition(array $conditionParameters)
{
return FsCodeSnippetConfigurationUtility::isAllLanguagesEnabled();
}
}
And the check for the actual TYPO3_CONF_VARS value is done in FsCodeSnippetConfigurationUtility:
namespace DanielGoerz\FsCodeSnippet\Utility;
class FsCodeSnippetConfigurationUtility
{
/**
* #return array
*/
private static function getExtensionConfiguration()
{
return unserialize($GLOBALS['TYPO3_CONF_VARS']['EXT']['extConf']['fs_code_snippet']);
}
/**
* #return bool
*/
public static function isAllLanguagesEnabled()
{
$conf = self::getExtensionConfiguration();
return !empty($conf['enableAllLanguages']);
}
}
Maybe that fits your needs.
Handle the configuration via Extension Manager and call ExtensionManagementUtility::addTypoScriptConstants() in your ext_localconf.php to set a TypoScript constant at runtime.
This way the value can be set at one location and is available both in lowlevel PHP and TypoScript setup.

Edit hidden records in frontend

I am building an extension to edit tt_news records in frontend.
I set setIgnoreEnableFields(TRUE) in my repository.
But if I try edit a hidden record, I get the error
Object with identity „12345" not found.
Any solution for this?
I am guessing you are using an action like
/**
* Single view of a news record
*
* #param \Vendor\Ext\Domain\Model\News $news news item
*/
public function detailAction(\Vendor\Ext\Domain\Model\News $news = null)
Your problem is, that the Repository is not used to fetch the record.
As a solution, remove the argument, clear the caches and try something like that
/**
* Single view of a news record
*
* #param \Vendor\Ext\Domain\Model\News $news news item
*/
public function detailAction() {
$id = (int)$this->request->getArgument('news');
if ($id) {
$news = $this->newsRepository->findByUid($previewNewsId);
}
}
Now you can manipulate the QuerySettings and use those.
The problem is the PropertyMapping. If extbase try to assign an uid (12345) to an Domain Object (tt_news) the "setEnableFields" setting of the Repository isn't respected. So you must fetch the object by yourself.
the simple solution is to do this in an initialize*Action for each "show" action. For editAction an example:
public function initializeEditAction() {
if ($this->request->hasArgument('news')) {
$newsUid = $this->request->getArgument('news');
if (!$this->newsRepository->findByUid($newsUid)) {
$defaultQuerySettings = $this->newsRepository->createQuery()->getQuerySettings();
$defaultQuerySettings->setIgnoreEnableFields(TRUE);
$this->newsRepository->setDefaultQuerySettings($defaultQuerySettings);
if ($news = $this->newsRepository->findByUid($newsUid)) {
$this->request->setArgument('news', $news);
}
}
}
}
The Hard Part is to get the object to update. As I never try this I have found an TypeConverter to fetch also hidden Records at https://gist.github.com/helhum/58a406fbb846b56a8b50
Maybe Instead to register the TypeConverter for everything (like the example in ext_localconf.php) you can try to assign it only in the initializeUpdateAction
public function initializeUpdateAction() {
if ($this->arguments->hasArgument('news')) {
$this->arguments->getArgument('news')->getPropertyMappingConfiguration()
->setTypeConverter('MyVendor\\MyExtension\\Property\\TypeConverters\\MyPersistenObjectConverter')
}
}

how to set form name directly on symfony3? [duplicate]

With Symfony 2.7, you could customize a form's name in your EntityType class with the method getName()
This is now deprecated. Is there another way to do that with Symfony 3.0 ?
I have custom prototype entry_rows for collections that I would need to use in different forms.
Since the name of the rows is based on the form's name, I would need to change the later in order to use them with a different form.
You should implements the getBlockPrefix method instead of getName as described in the migration guide here.
As example:
/**
* Returns the prefix of the template block name for this type.
*
* The block prefix defaults to the underscored short class name with
* the "Type" suffix removed (e.g. "UserProfileType" => "user_profile").
*
* #return string The prefix of the template block name
*/
public function getBlockPrefix()
{
return "form_name";
}
Hope this help
Depending on how your form is built, there is different ways to set the name of your form.
If you are creating the form through $this->createForm(CustomType::class):
$formFactory = $this->get('form.factory');
$form = $formFactory->createNamed('custom_form_name', CustomType::class);
If you are building the form from the controller directly through $this->createFormBuilder():
$formFactory = $this->get('form.factory');
$form = $formFactory->createNamedBuilder('custom_form_name', CustomType::class);
Look at the FormFactory and FormBuilder APIs for more information.
You can try it, remove prefix on field name
public function getBlockPrefix()
{
return null;
}

In Extbase 6.2, don't use uid for list page

When using Extbase's "show" action:
<f:link.action action="show" arguments="{event : event}">
I would like to look up said event by a special column ('customID').
The actual TYPO3-uid should NOT appear in the URL (with or without RealURL).
The reason is that the data has been imported, and the "real" uid is 'customId'.
There's always #biesior's approach using f:link.page https://stackoverflow.com/a/26145125/160968 – but I thought I'd try it with the official way.
(how) is it possible to do that in extbase/fluid?
This is possible. Let's assume your model Event has a property customId. So you generate your link like this:
<f:link.action action="show" arguments="{event : event.customId}">
The link generated will have a queryString like this:
?tx_myext[event]=9999
The showAction generated by the Extension Builder expects that the UID of the event is passed. The PropertyMapper then fetches the object automatically and assigns it to the view:
/**
* action show
*
* #param \Your\Extension\Domain\Model\Event $event
* #return void
*/
public function showAction(\Your\Extension\Domain\Model\Event $event) {
$this->view->assign('event', $event);
}
But in your case you cannot fetch the object by UID because you passed the customId. So you need to fetch the object yourself:
/**
* action show
*
* #param integer $event
* #return void
*/
public function showAction($event) {
$event = $this->eventRepository->findOneByCustomId($event);
$this->view->assign('event', $event);
}
The annotation #param integer $event tells TYPO3 that the parameter is "just" an integer. You then call the magic method findOneByCustomId from your eventRepository. findOne indicates that you want exactly one Event object back (and not a QueryResult), while the ByCustomId that queries an existing property of your Event model.
Why not use realUrl with lookUpTable? See here: https://wiki.typo3.org/Realurl/manual#-.3ElookUpTable