TYPO3 DataHandler:复制记录并将其与自身相关->进入循环

时间:2018-07-20 12:42:47

标签: typo3 typo3-8.x typo3-extensions

我正在开发具有重复日期的事件扩展。因此,我有一个重复的日期模式,并复制每个日期的记录。因此,记录与自身有关系: - 主要活动 -N个儿童活动

当前,我使用DataHandler方法copyRecord,它可以完美工作。但这只是复制记录,而不映射关系。 -主事件->应具有数据库中子代的数量 -N个子事件->应该与其父主事件有关系

数据库应如下所示: 赛事1(主赛事)| uid:1 |事件:0 | recurring_children:3(计数) 事件副本1 | uid:2 |事件:1 | recurring_children:0 事件副本2 | uid:3 |事件:1 | recurring_children:0 活动副本3 | uid:4 |事件:1 | recurring_children:0

我尝试了几种方法,但是都没有问题。

以下尝试在数据库中设置关系,但是创建更多事件(我想这是循环的,我必须建立条件以避免重复数据填充数据映射):

    public function processDatamap_afterDatabaseOperations(
    $status,
    $table,
    $recordUid,
    array $fields,
    \TYPO3\CMS\Core\DataHandling\DataHandler $parentObject){

    $event = BackendUtility::getRecord($table, $recordUid);
    if ($status === 'update') {
        /** @var \TYPO3\CMS\Core\DataHandling\DataHandler $tce */
        $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
        $tce->start(array(), array());
        $overrides = [
            'is_recurring_parent' => 0,
            'is_recurring_child' => 1,
            'recurring_weekdays' => '',
            'recurring_period_end' => '0000-00-00',
            'event' => $recordUid,
            'title' => 'FOOBAR'
        ];

        if ($event['is_recurring_parent']) {
            $foobar = $tce->copyRecord('tx_technoseumevents_domain_model_event', $event['uid'], $event['pid'], false, $overrides);
        }

T3版本8.7

对不起,我第一次将数据处理程序用于复杂任务。也许有人对我有暗示...

1 个答案:

答案 0 :(得分:1)

首先发生的递归表示您的体系结构中的一个问题,可能值得在此问题之前解决,因为它可以从根本上解决而不是处理症状。通常,记录不应该与自身相关,但是说,递归可以以其他方式发生,在您的用例中可能无法避免。

建议解决此问题:

  • 请考虑添加一个条件,以防止在您需要操作的一个表以外的表上调用代码。仅此一个原因实际上可能就是您的副本要递归的原因,因此这是处理的第一要因。
  • 如果可能的话,并且如果您不担心发生短路之类的事情,例如更改记录的标题TCA字段以在“ Copy of”之前加上或隐藏该副本,则可以切换到copyRecord_raw 。它采用的参数略有不同(与调用copyRecord相比,您可能需要重构以将某些参数作为重写数组的一部分传递)。这样做可以防止在复制的子代上调用钩子。
  • 您正在使用嵌套的DataHandler实例-在您的示例中,最好在$dataHandler实例上调用该方法。 DataHandler维护一个副本堆栈,但是(部分)它仅在您在同一实例中执行操作且仅针对某些特定的挂钩(即pre-type和非全局挂钩)时才起作用。
  • 最后,存在一个运行时缓存条目,其中包含一组已复制的记录。尽管访问和存储此高速缓存条目中的条目的实用程序方法不是公共可访问的-因此您不能从hook类中调用它们-您可以读取条目数组,对其进行操作并将其放回以防止递归处理同一记录。请参见DataHandler(https://github.com/TYPO3/TYPO3.CMS/blob/v8.7.17/typo3/sysext/core/Classes/DataHandling/DataHandler.php#L9034)中的isNestedElementCallRegistered方法。

最后的提示:数据库操作后挂钩可能在您不期望的时候被调用。例如,如果您复制一条记录并同时将其移动(例如:副本来自UI,而不是编程方式),则您在$fieldArray中收到的数组可能不是最终的数组(例如,{{1} }可能是一个意外值)。如果不了解这一点,并且上面的特性可能还会增加无意中导致递归操作的危险。

编辑:如果在TCA中使用双向关系,则移开一侧也可能会改善这种情况。例如,每个“日期”不必一定要知道与哪个事件相关联。要考虑的事情。