首页 文章

如何在TYPO3的挂钩中更新关系1:n的对象

提问于
浏览
1

我有一个A实体,它有一个属性调用B作为关系1:n从B到A.当我在TCA后端接口更新A时,当一个特定字段处于活动状态时,该解决方案运行一个类型为 function processDatamap_postProcessFieldArray (...) 的钩子

我必须创建一个B的新元素并保存在A的ObjectStorage属性中 . 这在执行时,创建一个对象并附加它,但不能保存在DB中 . 我已尝试使用extbase和Repository的功能,但它不起作用 . 在我的研究中确定了用于创建查询的框架Doctrine,类似于持久化行为,但在这种情况下我可以保存B的新对象 .

我的问题是:如何使用Doctrine进行构建查询,允许对对象A进行更新,添加新元素B并将此元素保存在DB中的关系中 .

我正在使用TYPO3 7.6

2 回答

  • 3

    您不应该在DataHandler挂钩中使用Extbase . 同样简单的数据库查询(无论是使用Dotrine还是TYPO3_DB)都不是在BE中创建实体的好主意 . 更好的方法是使用TYPO3 DataHandler API . 在创建/编辑实体A期间创建实体B的示例可能如此 .

    注册挂钩 typo3conf/ext/example/ext_localconf.php

    defined('TYPO3_MODE') || die('Access denied.');
    
    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass']['example'] = 'Vendor\\Example\\DataHandling\\DataHandler';
    

    typo3conf/ext/example/Classes/DataHandling/DataHandler.php

    namespace Vendor\Example\DataHandling;
    
    use TYPO3\CMS\Core\SingletonInterface;
    use TYPO3\CMS\Core\Utility\StringUtility;
    
    class DataHandler implements SingletonInterface
    {
        public function processDatamap_afterDatabaseOperations(
            string $status,
            string $table,
            $id,
            $fieldArray,
            \TYPO3\CMS\Core\DataHandling\DataHandler $dataHandler
        ) {
            // Do nothing if other table is processed
            if ($table !== 'tx_example_domain_model_entitya') {
                return;
            }
    
            // Get real UID of entity A if A is new record
            $idOfEntityA = $dataHandler->substNEWwithIDs[$id];
    
            // Example fields of entity B
            $entityB = [
                'sys_language_uid' => '0',
                'entitya' => $idOfEntityA,
                'hidden' => '0',
                'title' => 'I\'m entitty B',
                'starttime' => '0',
                'endtime' => '0',
                'pid' => $fieldArray['pid'],
            ];
    
            // Add entity B associated with entity A
            $dataHandler->start(
                [
                    'tx_example_domain_model_entityb' => [
                        StringUtility::getUniqueId('NEW') => $entityB
                    ]
                ],
                []
            );
            $dataHandler->process_datamap();
        }
    }
    

    测试8.7,但也适用于7.6 . 在这里您可以阅读有关DataHandler的更多信息https://docs.typo3.org/typo3cms/CoreApiReference/8.7/ApiOverview/Typo3CoreEngine/Database/

  • 2

    与前面的答案相反,我认为没有理由,为什么不应该在DataHandler Hooks中使用extbase . 我自己在一个扩展中使用动态对象,这些对象通过SOAP-Webservice进行同步 .

    你必须记住一些事情(在钩子函数内按此顺序):

    • 服从命名政策!! - 通过GeneralUtility :: makeInstance手动实例化ObjectManager - 手动获取所有存储库(我的意思是所有...也是你在钩子函数中使用的模型子项的存储库) . - 使用对象管理器=>而不是“新”创建新对象实例 .

    然后您可以像以前一样将子项添加到父项中..但不要忘记最后通过persistenceManager手动执行persistAll() .

    希望这可以帮助 . 基本上,通过DataMap Hook挂钩的函数就像一个通过ajax =>调用的静态函数,你必须确保获得所有所需的实用程序并手动管理类,因为typo3不会自动注入它们 .

    希望这会有所帮助,奥利弗

相关问题