Aljoscha
Aljoscha

Reputation: 306

TYPO3 - Retrieved TypoScript in itemsProcFunc are incomplete

I have following problem: We are overriding the tt_content TCA with a custom column which has an itemsProcFunc in it's config. In the function we try to retrieve the TypoScript-Settings, so we can display the items dynamically. The problem is: In the function we don't receive all the TypoScript-Settings, which are included but only some.

'itemsProcFunc' => 'Vendor\Ext\Backend\Hooks\TcaHook->addFields',

class TcaHook
{

        public function addFields($config){
            $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Object\\ObjectManager');
            $configurationManager = $objectManager->get('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManagerInterface');

            $setup = $configurationManager->getConfiguration(
                \TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT
            );
        }

$setup is now incomplete and doesn't contain the full TypoScript, for example some of the static-included TypoScript is missing.

Used TYPO3 7 LTS (7.6.18), PHP 7.0.* in composer-mode.

Does anybody know where the problem is? Is there some alternative?

Upvotes: 1

Views: 850

Answers (2)

Sybille Peters
Sybille Peters

Reputation: 3229

I had a similar problem (also with itemsProcFunc and retrieving TypoScript). In my case, the current page ID of the selected backend page was not known to the ConfigurationManager. Because of this it used the page id of the root page (e.g. 1) and some TypoScript templates were not loaded.


However, before we look at the solution, Euli made some good points in his answer:

  • Do not use extbase configuration manager in TCA functions
  • Use TSconfig instead of TypoScript for backend configuration

You may like to ask another question what you are trying to do specifically and why you need TypoScript in BE context.


For completeness sake, I tested this workaround, but I wouldn't recommend it because of the mentioned reasons and because I am not sure if this is best practice. (I only used it because I was patching an extension which was already using TypoScript in the TCA and I wanted to find out why it wasn't working. I will probably rework this part entirely.)

I am posting this in the hope that it may be helpful for similar problems.

public function populateItemsProcFunc(array &$config): array
{
    // workaround to set current page id for BackendConfigurationManager
    $_GET['id'] = $this->getPageId((int)($config['flexParentDatabaseRow']['pid'] ?? 0));

    $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
    $configurationManager = $objectManager->get(BackendConfigurationManager::class);
    $setting = $configurationManager->getTypoScriptSetup();
    $templates = $setting['plugin.']['tx_rssdisplay.']['settings.']['templates.'] ?? [];

    // ... some code removed
}

protected function getPageId(int $pid): int
{
   if ($pid > 0) {
       return $pid;
   }

   $row = BackendUtility::getRecord('tt_content', abs($pid), 'uid,pid');
   return $row['pid'];

}

The function getPageId() was derived from ext:news which also uses this in an itemsProcFunc but it then retrieves configuration from TSconfig. You may want to also look at that for an example: ext:news GeorgRinger\News\Hooks\ItemsProcFunc::user_templateLayout

If you look at the code in the TYPO3 core, it will try to get the current page id from

(int)GeneralUtility::_GP('id');

https://github.com/TYPO3/TYPO3.CMS/blob/90fa470e37d013769648a17a266eb3072dea4f56/typo3/sysext/extbase/Classes/Configuration/BackendConfigurationManager.php#L132

This will usually be set, but in an itemsProcFunc it may not (which was the case for me in TYPO3 10.4.14).

Upvotes: 1

Euli
Euli

Reputation: 1143

You maybe misunderstood the purpose of TypoScipt. It is a way of configuration for the Frontend. The Hook you mentioned is used in the TCA, whích is a Backend part of TYPO3. TypoScript usually isn't used for backend related stuff at all, because it is bound to a specific page template record. Instead in the backend, there is the TSConfig, that can be bound to a page, but also can be added globally. Another thing you are doing wrong is the use of the ObjectManager and the ConfigurationManager, which are classes of extbase, which isn't initialized in the backend. I would recommend to not use extbase in TCA, because the TCA is cached and loaded for every page request. Instead use TSConfig or give your configuration settings directly to the TCA. Do not initialize extbase and do not use extbase classes in these hooks. Depending on what you want to configure via TypoScript, you may want to do something like this:

'config' => [
    'type' => 'select',
    'renderType' => 'singleSelect',
    'items' => [
        ['EXT:my_ext/Resources/Private/Language/locallang_db.xlf:myfield.I.0', '']
    ],
    'itemsProcFunc' => \VENDOR\MyExt\UserFunctions\FormEngine\TypeSelectProcFunc::class . '->fillSelect',
    'customSetting' => 'somesetting'
]

and then access it in your class:

class TypeSelectProcFunc{
    public function fillSelect(&$params){
        if( $params['customSetting'] === 'somesetting' ){
            $params['items'][] = ['New item',1];
        }
    }
}

Upvotes: 1

Related Questions